Fixes associated with wildcard test classes.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / XMLHelper.cpp
1 /*\r
2  *  Copyright 2001-2006 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * XMLHelper.cpp\r
19  * \r
20  * A helper class for working with W3C DOM objects. \r
21  */\r
22 \r
23 #include "internal.h"\r
24 #include "exceptions.h"\r
25 #include "util/XMLHelper.h"\r
26 #include "util/XMLConstants.h"\r
27 \r
28 #include <xercesc/framework/MemBufFormatTarget.hpp>\r
29 #include <xercesc/util/XMLUniDefs.hpp>\r
30 \r
31 using namespace xmltooling;\r
32 \r
33 static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };\r
34     \r
35 bool XMLHelper::hasXSIType(const DOMElement* e)\r
36 {\r
37     if (e) {\r
38         if (e->hasAttributeNS(XMLConstants::XSI_NS, type)) {\r
39             return true;\r
40         }\r
41     }\r
42 \r
43     return false;\r
44 }\r
45 \r
46 QName* XMLHelper::getXSIType(const DOMElement* e)\r
47 {\r
48     DOMAttr* attribute = e->getAttributeNodeNS(XMLConstants::XSI_NS, type);\r
49     if (attribute) {\r
50         int i;\r
51         const XMLCh* attributeValue = attribute->getTextContent();\r
52         if (attributeValue && (i=XMLString::indexOf(attributeValue,chColon))>0) {\r
53             XMLCh* prefix=new XMLCh[i+1];\r
54             XMLString::subString(prefix,attributeValue,0,i);\r
55             prefix[i]=chNull;\r
56             QName* ret=new QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
57             delete[] prefix;\r
58             return ret;\r
59         }\r
60     }\r
61 \r
62     return NULL;\r
63 }\r
64 \r
65 DOMAttr* XMLHelper::getIdAttribute(const DOMElement* domElement)\r
66 {\r
67     if(!domElement->hasAttributes()) {\r
68         return NULL;\r
69     }\r
70     \r
71     DOMNamedNodeMap* attributes = domElement->getAttributes();\r
72     DOMAttr* attribute;\r
73     for(XMLSize_t i = 0; i < attributes->getLength(); i++) {\r
74         attribute = static_cast<DOMAttr*>(attributes->item(i));\r
75         if(attribute->isId()) {\r
76             return attribute;\r
77         }\r
78     }\r
79     \r
80     return NULL;\r
81 }\r
82 \r
83 QName* XMLHelper::getNodeQName(const DOMNode* domNode)\r
84 {\r
85     if (domNode)\r
86         return new QName(domNode->getNamespaceURI(), domNode->getLocalName(), domNode->getPrefix());\r
87     return NULL; \r
88 }\r
89 \r
90 QName* XMLHelper::getAttributeValueAsQName(const DOMAttr* attribute)\r
91 {\r
92     if (!attribute)\r
93         return NULL;\r
94     \r
95     int i;\r
96     const XMLCh* attributeValue=attribute->getTextContent();\r
97     if (attributeValue && (i=XMLString::indexOf(attributeValue,chColon))>0) {\r
98         XMLCh* prefix=new XMLCh[i+1];\r
99         XMLString::subString(prefix,attributeValue,0,i);\r
100         prefix[i]=chNull;\r
101         QName* ret=new QName(attribute->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
102         delete[] prefix;\r
103         return ret;\r
104     }\r
105     \r
106     return new QName(attribute->lookupNamespaceURI(NULL), attributeValue);\r
107 }\r
108 \r
109 DOMElement* XMLHelper::appendChildElement(DOMElement* parentElement, DOMElement* childElement)\r
110 {\r
111     DOMDocument* parentDocument = parentElement->getOwnerDocument();\r
112     if (childElement->getOwnerDocument() != parentDocument) {\r
113         childElement = static_cast<DOMElement*>(parentDocument->importNode(childElement, true));\r
114     }\r
115 \r
116     parentElement->appendChild(childElement);\r
117     return childElement;\r
118 }\r
119 \r
120 const XMLCh* XMLHelper::getTextContent(const DOMElement* e)\r
121 {\r
122     DOMNode* child=e->getFirstChild();\r
123     while (child) {\r
124         if (child->getNodeType()==DOMNode::TEXT_NODE)\r
125             return child->getNodeValue();\r
126         child=child->getNextSibling();\r
127     }\r
128     return NULL;\r
129 }\r
130 \r
131 void XMLHelper::serialize(const DOMElement* e, std::string& buf)\r
132 {\r
133     static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
134     static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
135     DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);\r
136     DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();\r
137     serializer->setEncoding(UTF8);\r
138     try {\r
139         MemBufFormatTarget target;\r
140         if (!serializer->writeNode(&target,*e))\r
141             throw XMLParserException("unable to serialize XML");\r
142         buf.erase();\r
143         buf.append(reinterpret_cast<const char*>(target.getRawBuffer()),target.getLen());\r
144         serializer->release();\r
145     }\r
146     catch (...) {\r
147         serializer->release();\r
148         throw;\r
149     }\r
150 }\r