diff options
Diffstat (limited to 'src/uscxml/util')
-rw-r--r-- | src/uscxml/util/DOM.cpp | 288 | ||||
-rw-r--r-- | src/uscxml/util/DOM.h | 27 |
2 files changed, 226 insertions, 89 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 } diff --git a/src/uscxml/util/DOM.h b/src/uscxml/util/DOM.h index 2b133d8..48ad321 100644 --- a/src/uscxml/util/DOM.h +++ b/src/uscxml/util/DOM.h @@ -57,9 +57,6 @@ public: const std::string& ns = ""); static std::string idForNode(const XERCESC_NS::DOMNode* node); - static std::list<XERCESC_NS::DOMNode*> getElementsByType(const XERCESC_NS::DOMNode* root, - XERCESC_NS::DOMNode::NodeType type); - static std::list<XERCESC_NS::DOMElement*> inPostFixOrder(const std::set<std::string>& elements, const XERCESC_NS::DOMElement* root, const bool includeEmbeddedDoc = false); @@ -83,8 +80,28 @@ public: static std::list<XERCESC_NS::DOMNode*> filterChildType(const XERCESC_NS::DOMNode::NodeType type, const std::list<XERCESC_NS::DOMNode*>& nodeSet, bool recurse = false); - protected: + enum Order { + POSTFIX, + DOCUMENT, + NO_RECURSE + }; + + static void filterElementGeneric(const std::set<std::string>& elements, + std::list<XERCESC_NS::DOMElement*>& result, + const XERCESC_NS::DOMElement* root, + const Order order, + const bool includeEmbeddedDoc, + const bool includeRoot); + + static void filterTypeGeneric(const std::set<XERCESC_NS::DOMNode::NodeType>& types, + std::list<XERCESC_NS::DOMNode*>& result, + const XERCESC_NS::DOMElement* root, + const Order order, + const bool includeEmbeddedDoc, + const bool includeRoot); + +#if 0 static void inPostFixOrder(const std::set<std::string>& elements, const XERCESC_NS::DOMElement* root, const bool includeEmbeddedDoc, @@ -94,7 +111,7 @@ protected: const XERCESC_NS::DOMElement* root, const bool includeEmbeddedDoc, std::list<XERCESC_NS::DOMElement*>& nodes); - +#endif }; |