summaryrefslogtreecommitdiffstats
path: root/src/uscxml/util/DOM.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/util/DOM.cpp')
-rw-r--r--src/uscxml/util/DOM.cpp288
1 files changed, 204 insertions, 84 deletions
diff --git a/src/uscxml/util/DOM.cpp b/src/uscxml/util/DOM.cpp
index f661ebb..c21dee1 100644
--- a/src/uscxml/util/DOM.cpp
+++ b/src/uscxml/util/DOM.cpp
@@ -21,9 +21,7 @@
#include "uscxml/Common.h"
#include "uscxml/util/Convenience.h"
-//#include "uscxml/util/UUID.h"
#include "uscxml/util/DOM.h"
-//#include "uscxml/util/Convenience.h"
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
@@ -31,9 +29,6 @@
#include "uscxml/interpreter/Logging.h"
-//#include <glog/logging.h>
-//#include <boost/algorithm/string.hpp>
-
namespace uscxml {
using namespace XERCESC_NS;
@@ -42,12 +37,16 @@ std::ostream& operator<< (std::ostream& os, const DOMNode& node) {
DOMImplementation *implementation = DOMImplementationRegistry::getDOMImplementation(X("LS"));
DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
+
if (serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))
serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
- serializer->setNewLine(XMLString::transcode("\r\n"));
- X output = serializer->writeToString(&node);
- os << output;
+ serializer->setNewLine(X("\r\n"));
+ XMLCh* outString = serializer->writeToString(&node);
+ os << X(outString);
+ XMLString::release(&outString);
+
+ delete (serializer);
return os;
}
@@ -220,108 +219,142 @@ bool DOMUtils::isDescendant(const DOMNode* s1,
return false;
}
-std::list<DOMElement*> DOMUtils::inPostFixOrder(const std::set<std::string>& elements,
- const DOMElement* root,
- const bool includeEmbeddedDoc) {
- std::list<DOMElement*> nodes;
- inPostFixOrder(elements, root, includeEmbeddedDoc, nodes);
- return nodes;
-}
+void DOMUtils::filterElementGeneric(const std::set<std::string>& elements,
+ std::list<DOMElement*>& result,
+ const DOMElement* root,
+ const Order order,
+ const bool includeEmbeddedDoc,
+ const bool includeRoot) {
-void DOMUtils::inPostFixOrder(const std::set<std::string>& elements,
- const DOMElement* root,
- const bool includeEmbeddedDoc,
- std::list<DOMElement*>& nodes) {
-
- if (root == NULL)
+ if (!root)
return;
- for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
- if (!includeEmbeddedDoc && LOCALNAME(childElem) == "scxml")
- continue;
- inPostFixOrder(elements, childElem, includeEmbeddedDoc, nodes);
+ if ((order == NO_RECURSE || order == DOCUMENT) &&
+ includeRoot &&
+ elements.find(TAGNAME(root)) != elements.end()) {
+ result.push_back((DOMElement*)root);
}
- for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
- if (!includeEmbeddedDoc && TAGNAME(childElem) == XML_PREFIX(root).str() + "scxml")
- continue;
- if (elements.find(TAGNAME(childElem)) != elements.end()) {
- nodes.push_back((DOMElement*)childElem);
+ if (root->getNodeType() == DOMNode::ELEMENT_NODE && root->hasChildNodes()) {
+ DOMElement* currElement = root->getFirstElementChild();
+ while (currElement) {
+ if (order == NO_RECURSE) {
+ if (elements.find(TAGNAME(currElement)) != elements.end()) {
+ result.push_back(currElement);
+ }
+ } else {
+ if (includeEmbeddedDoc || TAGNAME(currElement) != XML_PREFIX(root).str() + "scxml") {
+ filterElementGeneric(elements, result, currElement, order, includeEmbeddedDoc, true);
+ }
+ }
+ currElement = currElement->getNextElementSibling();
}
}
-}
-//TODO: Unify recursive search in DOM
+ if (order == POSTFIX &&
+ includeRoot &&
+ elements.find(TAGNAME(root)) != elements.end()) {
+ result.push_back((DOMElement*)root);
+ }
-std::list<DOMElement*> DOMUtils::inDocumentOrder(const std::set<std::string>& elements,
- const DOMElement* root,
- const bool includeEmbeddedDoc) {
- std::list<DOMElement*> nodes;
- inDocumentOrder(elements, root, includeEmbeddedDoc, nodes);
- return nodes;
}
-void DOMUtils::inDocumentOrder(const std::set<std::string>& elements,
- const DOMElement* root,
- const bool includeEmbeddedDoc,
- std::list<DOMElement*>& nodes) {
- if (root == NULL)
+
+void DOMUtils::filterTypeGeneric(const std::set<DOMNode::NodeType>& types,
+ std::list<DOMNode*>& result,
+ const DOMElement* root,
+ const Order order,
+ const bool includeEmbeddedDoc,
+ const bool includeRoot) {
+
+ if (!root)
return;
- if (elements.find(TAGNAME(root)) != elements.end()) {
- nodes.push_back((DOMElement*)root);
+ if ((order == NO_RECURSE || order == DOCUMENT) &&
+ includeRoot &&
+ types.find(root->getNodeType()) != types.end()) {
+ result.push_back((DOMNode*)root);
}
- /// @todo: item from getChildNodes is O(N)!
- DOMElement* child = root->getFirstElementChild();
- while(child) {
- if (includeEmbeddedDoc || TAGNAME(child) != XML_PREFIX(root).str() + "scxml") {
- inDocumentOrder(elements, child, includeEmbeddedDoc, nodes);
+ if (root->getNodeType() == DOMNode::ELEMENT_NODE && root->hasChildNodes()) {
+ DOMNode* currNode = root->getFirstChild();
+ while (currNode) {
+ if (currNode->getNodeType() != DOMNode::ELEMENT_NODE) {
+ if (types.find(currNode->getNodeType()) != types.end()) {
+ result.push_back(currNode);
+ }
+ } else {
+ if (currNode->getNodeType() == DOMNode::ELEMENT_NODE) {
+ DOMElement* currElement = (DOMElement*)currNode;
+ if (includeEmbeddedDoc || TAGNAME(currElement) != XML_PREFIX(root).str() + "scxml") {
+ filterTypeGeneric(types, result, currElement, order, includeEmbeddedDoc, true);
+ }
+ }
+ }
+ currNode = currNode->getNextSibling();
}
+ }
- child = child->getNextElementSibling();
+ if (order == POSTFIX &&
+ includeRoot &&
+ types.find(root->getNodeType()) != types.end()) {
+ result.push_back((DOMNode*)root);
}
-}
-std::list<DOMNode*> DOMUtils::getElementsByType(const DOMNode* root,
- DOMNode::NodeType type) {
- std::list<DOMNode*> result;
- std::list<DOMNode*> stack;
- std::list<DOMNode*>::iterator stackIter;
+}
- if (!root)
- return result;
-
- stack.push_back((DOMNode*)root);
- while(stack.size() > 0) {
-// for(stackIter = stack.begin(); stackIter != stack.end(); stackIter++) {
-// std::cout << stackIter->getNodeType() << " " << stackIter->getLocalName() << " " << stackIter->getNodeValue() << std::endl;
-// }
-// std::cout << std::endl;
-
- DOMNode* currNode = stack.back();
- if (currNode->hasChildNodes()) {
- stack.push_back(currNode->getFirstChild());
- continue;
- }
+#if 1
+std::list<DOMElement*> DOMUtils::inPostFixOrder(const std::set<std::string>& elements,
+ const DOMElement* root,
+ const bool includeEmbeddedDoc) {
+ std::list<DOMElement*> result;
+ filterElementGeneric(elements, result, root, POSTFIX, includeEmbeddedDoc, true);
+ return result;
+}
+#else
+std::list<DOMElement*> DOMUtils::inPostFixOrder(const std::set<std::string>& elements,
+ const DOMElement* root,
+ const bool includeEmbeddedDoc) {
+ std::list<DOMElement*> nodes;
+ inPostFixOrder(elements, root, includeEmbeddedDoc, nodes);
+ return nodes;
+}
+#endif
- // roll back stack and pop everyone without next sibling
- do {
- currNode = stack.back();
- if (currNode->getNodeType() == type)
- result.push_back(currNode);
- stack.pop_back();
- if (currNode->getNextSibling()) {
- stack.push_back(currNode->getNextSibling());
- break;
- }
- } while(stack.size() > 0);
- }
+#if 1
+std::list<DOMElement*> DOMUtils::inDocumentOrder(const std::set<std::string>& elements,
+ const DOMElement* root,
+ const bool includeEmbeddedDoc) {
+ std::list<DOMElement*> result;
+ filterElementGeneric(elements, result, root, DOCUMENT, includeEmbeddedDoc, true);
return result;
}
+#else
+std::list<DOMElement*> DOMUtils::inDocumentOrder(const std::set<std::string>& elements,
+ const DOMElement* root,
+ const bool includeEmbeddedDoc) {
+ std::list<DOMElement*> nodes;
+ inDocumentOrder(elements, root, includeEmbeddedDoc, nodes);
+ return nodes;
+}
+#endif
+#if 1
+std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName,
+ const std::list<DOMElement*>& nodeSet,
+ bool recurse) {
+ std::list<DOMElement*> filteredChildElems;
+ std::list<DOMElement*>::const_iterator nodeIter = nodeSet.begin();
+ while(nodeIter != nodeSet.end()) {
+ if ((*nodeIter)->getNodeType() == DOMNode::ELEMENT_NODE)
+ filterElementGeneric({ tagName }, filteredChildElems, (DOMElement*)(*nodeIter), (recurse ? DOCUMENT : NO_RECURSE), true, false);
+ nodeIter++;
+ }
+ return filteredChildElems;
+}
+#else
std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName,
const std::list<DOMElement*>& nodeSet,
bool recurse) {
@@ -335,7 +368,18 @@ std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName,
}
return filteredChildElems;
}
+#endif
+#if 1
+std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName,
+ const DOMElement* node,
+ bool recurse) {
+
+ std::list<DOMElement*> result;
+ filterElementGeneric({ tagName }, result, node, (recurse ? DOCUMENT : NO_RECURSE), true, false);
+ return result;
+}
+#else
std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName,
const DOMElement* node,
bool recurse) {
@@ -358,7 +402,22 @@ std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName,
return filteredChildElems;
}
+#endif
+#if 1
+std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type,
+ const std::list<DOMNode*>& nodeSet,
+ bool recurse) {
+ std::list<DOMNode*> filteredChildType;
+ std::list<DOMNode*>::const_iterator nodeIter = nodeSet.begin();
+ while(nodeIter != nodeSet.end()) {
+ if ((*nodeIter)->getNodeType() == DOMNode::ELEMENT_NODE)
+ filterTypeGeneric({ type }, filteredChildType, (DOMElement*)(*nodeIter), (recurse ? DOCUMENT : NO_RECURSE), true, false);
+ nodeIter++;
+ }
+ return filteredChildType;
+}
+#else
std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type,
const std::list<DOMNode*>& nodeSet,
bool recurse) {
@@ -371,7 +430,21 @@ std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type,
}
return filteredChildType;
}
+#endif
+#if 1
+std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type,
+ const DOMNode* node,
+ bool recurse) {
+
+ std::list<DOMNode*> result;
+ if (node) {
+ assert(node->getNodeType() == DOMNode::ELEMENT_NODE);
+ }
+ filterTypeGeneric({ type }, result, (DOMElement*)node, (recurse ? DOCUMENT : NO_RECURSE), true, false);
+ return result;
+}
+#else
std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type,
const DOMNode* node,
bool recurse) {
@@ -392,6 +465,53 @@ std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type,
}
return filteredChildTypes;
}
+#endif
+
+#if 0
+void DOMUtils::inPostFixOrder(const std::set<std::string>& elements,
+ const DOMElement* root,
+ const bool includeEmbeddedDoc,
+ std::list<DOMElement*>& nodes) {
+
+ if (root == NULL)
+ return;
+
+ for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
+ if (!includeEmbeddedDoc && LOCALNAME(childElem) == "scxml")
+ continue;
+ inPostFixOrder(elements, childElem, includeEmbeddedDoc, nodes);
+
+ }
+ for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
+ if (!includeEmbeddedDoc && TAGNAME(childElem) == XML_PREFIX(root).str() + "scxml")
+ continue;
+
+ if (elements.find(TAGNAME(childElem)) != elements.end()) {
+ nodes.push_back((DOMElement*)childElem);
+ }
+ }
+}
+void DOMUtils::inDocumentOrder(const std::set<std::string>& elements,
+ const DOMElement* root,
+ const bool includeEmbeddedDoc,
+ std::list<DOMElement*>& nodes) {
+ if (root == NULL)
+ return;
+
+ if (elements.find(TAGNAME(root)) != elements.end()) {
+ nodes.push_back((DOMElement*)root);
+ }
+ /// @todo: item from getChildNodes is O(N)!
+ DOMElement* child = root->getFirstElementChild();
+ while(child) {
+ if (includeEmbeddedDoc || TAGNAME(child) != XML_PREFIX(root).str() + "scxml") {
+ inDocumentOrder(elements, child, includeEmbeddedDoc, nodes);
+ }
+
+ child = child->getNextElementSibling();
+ }
+}
+#endif
}