Credential resolver plugin
[shibboleth/cpp-xmltooling.git] / xmltooling / util / XMLHelper.cpp
index cdd32a8..1bf8d5d 100644 (file)
  */\r
 \r
 #include "internal.h"\r
+#include "exceptions.h"\r
 #include "util/XMLHelper.h"\r
 #include "util/XMLConstants.h"\r
 \r
+#include <xercesc/framework/MemBufFormatTarget.hpp>\r
 #include <xercesc/util/XMLUniDefs.hpp>\r
 \r
 using namespace xmltooling;\r
 \r
 static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };\r
     \r
-bool XMLHelper::hasXSIType(DOMElement* e)\r
+bool XMLHelper::hasXSIType(const DOMElement* e)\r
 {\r
     if (e) {\r
         if (e->hasAttributeNS(XMLConstants::XSI_NS, type)) {\r
@@ -41,26 +43,31 @@ bool XMLHelper::hasXSIType(DOMElement* e)
     return false;\r
 }\r
 \r
-QName* XMLHelper::getXSIType(DOMElement* e)\r
+QName* XMLHelper::getXSIType(const DOMElement* e)\r
 {\r
     DOMAttr* attribute = e->getAttributeNodeNS(XMLConstants::XSI_NS, type);\r
     if (attribute) {\r
-        int i;\r
         const XMLCh* attributeValue = attribute->getTextContent();\r
-        if (attributeValue && (i=XMLString::indexOf(attributeValue,chColon))>0) {\r
-            XMLCh* prefix=new XMLCh[i+1];\r
-            XMLString::subString(prefix,attributeValue,0,i);\r
-            prefix[i]=chNull;\r
-            QName* ret=new QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
-            delete[] prefix;\r
-            return ret;\r
+        if (attributeValue && *attributeValue) {\r
+            int i;\r
+            if ((i=XMLString::indexOf(attributeValue,chColon))>0) {\r
+                XMLCh* prefix=new XMLCh[i+1];\r
+                XMLString::subString(prefix,attributeValue,0,i);\r
+                prefix[i]=chNull;\r
+                QName* ret=new QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
+                delete[] prefix;\r
+                return ret;\r
+            }\r
+            else {\r
+                return new QName(e->lookupNamespaceURI(&chNull), attributeValue);\r
+            }\r
         }\r
     }\r
 \r
     return NULL;\r
 }\r
 \r
-DOMAttr* XMLHelper::getIdAttribute(DOMElement* domElement)\r
+DOMAttr* XMLHelper::getIdAttribute(const DOMElement* domElement)\r
 {\r
     if(!domElement->hasAttributes()) {\r
         return NULL;\r
@@ -78,14 +85,14 @@ DOMAttr* XMLHelper::getIdAttribute(DOMElement* domElement)
     return NULL;\r
 }\r
 \r
-QName* XMLHelper::getNodeQName(DOMNode* domNode)\r
+QName* XMLHelper::getNodeQName(const DOMNode* domNode)\r
 {\r
     if (domNode)\r
         return new QName(domNode->getNamespaceURI(), domNode->getLocalName(), domNode->getPrefix());\r
     return NULL; \r
 }\r
 \r
-QName* XMLHelper::getAttributeValueAsQName(DOMAttr* attribute)\r
+QName* XMLHelper::getAttributeValueAsQName(const DOMAttr* attribute)\r
 {\r
     if (!attribute)\r
         return NULL;\r
@@ -114,3 +121,109 @@ DOMElement* XMLHelper::appendChildElement(DOMElement* parentElement, DOMElement*
     parentElement->appendChild(childElement);\r
     return childElement;\r
 }\r
+\r
+const XMLCh* XMLHelper::getTextContent(const DOMElement* e)\r
+{\r
+    DOMNode* child=e->getFirstChild();\r
+    while (child) {\r
+        if (child->getNodeType()==DOMNode::TEXT_NODE)\r
+            return child->getNodeValue();\r
+        child=child->getNextSibling();\r
+    }\r
+    return NULL;\r
+}\r
+\r
+DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n, const XMLCh* localName)\r
+{\r
+    DOMNode* child = n->getFirstChild();\r
+    while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)\r
+        child = child->getNextSibling();\r
+    if (child && localName) {\r
+        if (!XMLString::equals(localName,child->getLocalName()))\r
+            return getNextSiblingElement(child, localName);\r
+    }\r
+    return static_cast<DOMElement*>(child);\r
+}    \r
+\r
+DOMElement* XMLHelper::getLastChildElement(const DOMNode* n, const XMLCh* localName)\r
+{\r
+    DOMNode* child = n->getLastChild();\r
+    while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)\r
+        child = child->getPreviousSibling();\r
+    if (child && localName) {\r
+        if (!XMLString::equals(localName,child->getLocalName()))\r
+            return getPreviousSiblingElement(child, localName);\r
+    }\r
+    return static_cast<DOMElement*>(child);\r
+}    \r
+\r
+DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
+{\r
+    DOMElement* e = getFirstChildElement(n, localName);\r
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
+        e = getNextSiblingElement(e, localName);\r
+    return e;\r
+}\r
+\r
+DOMElement* XMLHelper::getLastChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
+{\r
+    DOMElement* e = getLastChildElement(n, localName);\r
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
+        e = getPreviousSiblingElement(e, localName);\r
+    return e;\r
+}\r
+\r
+DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n, const XMLCh* localName)\r
+{\r
+    DOMNode* sib = n->getNextSibling();\r
+    while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)\r
+        sib = sib->getNextSibling();\r
+    if (sib && localName) {\r
+        if (!XMLString::equals(localName,sib->getLocalName()))\r
+            return getNextSiblingElement(sib, localName);\r
+    }   \r
+    return static_cast<DOMElement*>(sib);\r
+}\r
+\r
+DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n, const XMLCh* localName)\r
+{\r
+    DOMNode* sib = n->getPreviousSibling();\r
+    while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)\r
+        sib = sib->getPreviousSibling();\r
+    if (sib && localName) {\r
+        if (!XMLString::equals(localName,sib->getLocalName()))\r
+            return getPreviousSiblingElement(sib, localName);\r
+    }   \r
+    return static_cast<DOMElement*>(sib);\r
+}\r
+\r
+DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
+{\r
+    DOMElement* e = getNextSiblingElement(n, localName);\r
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
+        e = getNextSiblingElement(e, localName);\r
+    return e;\r
+}\r
+\r
+DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
+{\r
+    DOMElement* e = getPreviousSiblingElement(n, localName);\r
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
+        e = getPreviousSiblingElement(e, localName);\r
+    return e;\r
+}\r
+\r
+void XMLHelper::serialize(const DOMElement* e, std::string& buf)\r
+{\r
+    static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
+    static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
+    DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);\r
+    DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();\r
+    XercesJanitor<DOMWriter> janitor(serializer);\r
+    serializer->setEncoding(UTF8);\r
+    MemBufFormatTarget target;\r
+    if (!serializer->writeNode(&target,*e))\r
+        throw XMLParserException("unable to serialize XML");\r
+    buf.erase();\r
+    buf.append(reinterpret_cast<const char*>(target.getRawBuffer()),target.getLen());\r
+}\r