Credential resolver plugin
[shibboleth/cpp-xmltooling.git] / xmltooling / util / XMLHelper.cpp
index d4cd911..1bf8d5d 100644 (file)
@@ -47,15 +47,20 @@ QName* XMLHelper::getXSIType(const DOMElement* e)
 {\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
@@ -117,23 +122,108 @@ DOMElement* XMLHelper::appendChildElement(DOMElement* parentElement, DOMElement*
     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
-    try {\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
-        serializer->release();\r
-    }\r
-    catch (...) {\r
-        serializer->release();\r
-        throw;\r
-    }\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