#include #include "uscxml/config.h" #include "uscxml/Common.h" #include #include #include #include #include "uscxml/Interpreter.h" #include "uscxml/dom/DOMUtils.h" #include "uscxml/dom/NameSpacingParser.h" using namespace Arabica::DOM; using namespace Arabica::XPath; using namespace uscxml; #define VALIDATE \ std::pair, NameSpaceInfo> parsed = parse(xmlSS.str());\ Document origDoc = parsed.first;\ NameSpaceInfo origNS = parsed.second;\ validateRootFoo(parsed);\ insertBar(parsed);\ std::cout << parsed.first << std::endl;\ validateRootFooBar(parsed);\ parsed = cloneDocument(parsed);\ insertBaz(parsed);\ std::cout << parsed.first << std::endl;\ validateRootFooBarBaz(parsed);\ assert(DOMUtils::filterChildElements(origNS.xmlNSPrefix + "bar", origDoc.getDocumentElement()).size() == 3);\ assert(DOMUtils::filterChildElements(origNS.xmlNSPrefix + "baz", origDoc.getDocumentElement()).size() == 0); /** Test DOM manipulations and document cloning with different namespace scenarios */ static Arabica::XPath::XPath _xpath; std::pair, NameSpaceInfo> parse(const std::string xmlString) { NameSpacingParser parser = NameSpacingParser::fromXML(xmlString); if (parser.errorsReported()) assert(false); return std::make_pair(parser.getDocument(), parser.nameSpace); } std::pair, NameSpaceInfo> cloneDocument(std::pair, NameSpaceInfo>& parsed) { NameSpaceInfo nsInfo = parsed.second; Document document = parsed.first; Document clonedDocument; DOMImplementation domFactory = Arabica::SimpleDOM::DOMImplementation::getDOMImplementation(); clonedDocument = domFactory.createDocument(document.getNamespaceURI(), "", 0); Node child = document.getFirstChild(); while (child) { Node newNode = clonedDocument.importNode(child, true); clonedDocument.appendChild(newNode); child = child.getNextSibling(); } return std::make_pair(clonedDocument, nsInfo); } void insertBar(std::pair, NameSpaceInfo>& parsed) { NameSpaceInfo nsInfo = parsed.second; Document document = parsed.first; Node root = document.getDocumentElement(); for (size_t i = 0; i < 3; i++) { Element bar = document.createElementNS(nsInfo.nsURL, "bar"); // if (nsInfo.nsToPrefix.find(nsInfo.nsURL) != nsInfo.nsToPrefix.end()) nsInfo.setPrefix(bar); root.appendChild(bar); } } void insertBaz(std::pair, NameSpaceInfo>& parsed) { NameSpaceInfo nsInfo = parsed.second; Document document = parsed.first; Node root = document.getDocumentElement(); for (size_t i = 0; i < 3; i++) { Element baz = document.createElementNS(nsInfo.nsURL, "baz"); nsInfo.setPrefix(baz); root.appendChild(baz); } } static void validateRootFoo(std::pair, NameSpaceInfo>& parsed) { NameSpaceInfo nsInfo = parsed.second; Document document = parsed.first; Node root = document.getDocumentElement(); _xpath.setNamespaceContext(*nsInfo.getNSContext()); assert(TAGNAME_CAST(root) == nsInfo.xmlNSPrefix + "root"); assert(LOCALNAME_CAST(root) == "root"); NodeSet foosFiltered = DOMUtils::filterChildElements(nsInfo.xmlNSPrefix + "foo", root); assert(foosFiltered.size() == 3); NodeSet foosXPath = _xpath.evaluate("//" + nsInfo.xpathPrefix + "foo", root).asNodeSet(); assert(foosXPath.size() == 3); for (size_t i = 0; i < 3; i++) { assert(foosFiltered[i] == foosXPath[i]); assert(TAGNAME_CAST(foosFiltered[i]) == nsInfo.xmlNSPrefix + "foo"); assert(LOCALNAME_CAST(foosFiltered[i]) == "foo"); } } static void validateRootFooBar(std::pair, NameSpaceInfo>& parsed) { validateRootFoo(parsed); NameSpaceInfo nsInfo = parsed.second; Document document = parsed.first; Node root = document.getDocumentElement(); _xpath.setNamespaceContext(*nsInfo.getNSContext()); NodeSet barsFiltered = DOMUtils::filterChildElements(nsInfo.xmlNSPrefix + "bar", root); assert(barsFiltered.size() == 3); NodeSet barsXPath = _xpath.evaluate("//" + nsInfo.xpathPrefix + "bar", root).asNodeSet(); assert(barsXPath.size() == 3); for (size_t i = 0; i < 3; i++) { assert(barsFiltered[i] == barsXPath[i]); assert(TAGNAME_CAST(barsFiltered[i]) == nsInfo.xmlNSPrefix + "bar"); assert(LOCALNAME_CAST(barsFiltered[i]) == "bar"); } } static void validateRootFooBarBaz(std::pair, NameSpaceInfo>& parsed) { validateRootFooBar(parsed); NameSpaceInfo nsInfo = parsed.second; Document document = parsed.first; Node root = document.getDocumentElement(); _xpath.setNamespaceContext(*nsInfo.getNSContext()); assert(TAGNAME_CAST(root) == nsInfo.xmlNSPrefix + "root"); assert(LOCALNAME_CAST(root) == "root"); NodeSet bazsFiltered = DOMUtils::filterChildElements(nsInfo.xmlNSPrefix + "baz", root); assert(bazsFiltered.size() == 3); NodeSet bazsXPath = _xpath.evaluate("//" + nsInfo.xpathPrefix + "baz", root).asNodeSet(); assert(bazsXPath.size() == 3); for (size_t i = 0; i < 3; i++) { assert(bazsFiltered[i] == bazsXPath[i]); assert(TAGNAME_CAST(bazsFiltered[i]) == nsInfo.xmlNSPrefix + "baz"); assert(LOCALNAME_CAST(bazsFiltered[i]) == "baz"); } } int main(int argc, char** argv) { // No namespaces at all { std::stringstream xmlSS; xmlSS << "" << std::endl; VALIDATE } // default namespace { std::stringstream xmlSS; xmlSS << "\ \ \ \ " << std::endl; VALIDATE } // explicit namespaces { std::stringstream xmlSS; xmlSS << "\ \ \ \ " << std::endl; VALIDATE } // mixed namespaces { std::stringstream xmlSS; xmlSS << "\ \ \ \ \ " << std::endl; VALIDATE } // mixed namespaces with different default NS { std::stringstream xmlSS; xmlSS << "\ \ \ \ \ " << std::endl; VALIDATE } }