9fe1e621bcb7953d23cf2dfdf49ed1f66d80237a
[shibboleth/cpp-xmltooling.git] / xmltooling / util / XMLHelper.h
1 /*
2  *  Copyright 2001-2010 Internet2
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file xmltooling/util/XMLHelper.h
19  *
20  * A helper class for working with W3C DOM objects.
21  */
22
23 #ifndef __xmltooling_xmlhelper_h__
24 #define __xmltooling_xmlhelper_h__
25
26 #include <xmltooling/base.h>
27
28 #include <set>
29 #include <iostream>
30 #include <xercesc/dom/DOM.hpp>
31
32 namespace xmltooling {
33
34     class XMLTOOL_API QName;
35     class XMLTOOL_API XMLObject;
36
37     /**
38      * RAII wrapper for Xerces resources.
39      */
40     template<class T> class XercesJanitor
41     {
42         MAKE_NONCOPYABLE(XercesJanitor);
43         T* m_held;
44     public:
45         /**
46          * Constructor
47          *
48          * @param resource  object to release when leaving scope
49          */
50         XercesJanitor(T* resource) : m_held(resource) {}
51
52         ~XercesJanitor() {
53             if (m_held)
54                 m_held->release();
55         }
56
57         /**
58          * Returns resource held by this object.
59          *
60          * @return  the resource held or NULL
61          */
62         T* get() {
63             return m_held;
64         }
65
66         /**
67          * Returns resource held by this object.
68          *
69          * @return  the resource held or NULL
70          */
71         T* operator->() {
72             return m_held;
73         }
74
75         /**
76          * Returns resource held by this object and releases it to the caller.
77          *
78          * @return  the resource held or NULL
79          */
80         T* release() {
81             T* ret=m_held;
82             m_held=NULL;
83             return ret;
84         }
85     };
86
87     /**
88      * A helper class for working with W3C DOM objects.
89      */
90     class XMLTOOL_API XMLHelper
91     {
92     public:
93         /**
94          * Checks if the given element has an xsi:type defined for it
95          *
96          * @param e the DOM element
97          * @return true if there is a type, false if not
98          */
99         static bool hasXSIType(const xercesc::DOMElement* e);
100
101         /**
102          * Gets the XSI type for a given element if it has one.
103          *
104          * @param e the element
105          * @return the type or null
106          */
107         static QName* getXSIType(const xercesc::DOMElement* e);
108
109         /**
110          * Gets the ID attribute of a DOM element.
111          *
112          * @param domElement the DOM element
113          * @return the ID attribute or null if there isn't one
114          */
115         static xercesc::DOMAttr* getIdAttribute(const xercesc::DOMElement* domElement);
116
117         /**
118          * Attempts to locate an XMLObject from this point downward in the tree whose
119          * XML ID matches the supplied value.
120          *
121          * @param tree  root of tree to search
122          * @param id    ID value to locate
123          * @return XMLObject in the tree with a matching ID value, or NULL
124          */
125         static const XMLObject* getXMLObjectById(const XMLObject& tree, const XMLCh* id);
126
127         /**
128          * Attempts to locate an XMLObject from this point downward in the tree whose
129          * XML ID matches the supplied value.
130          *
131          * @param tree  root of tree to search
132          * @param id    ID value to locate
133          * @return XMLObject in the tree with a matching ID value, or NULL
134          */
135         static XMLObject* getXMLObjectById(XMLObject& tree, const XMLCh* id);
136
137         /**
138          * Returns a list of non-visibly-used namespace prefixes found in a tree.
139          *
140          * @param tree      root of tree to search
141          * @param prefixes  container to store prefix list
142          */
143         static void getNonVisiblyUsedPrefixes(const XMLObject& tree, std::set<xstring>& prefixes);
144
145         /**
146          * Gets the QName for the given DOM node.
147          *
148          * @param domNode the DOM node
149          * @return the QName for the element or null if the element was null
150          */
151         static QName* getNodeQName(const xercesc::DOMNode* domNode);
152
153         /**
154          * @deprecated
155          * Constructs a QName from an attribute's value.
156          *
157          * @param attribute the attribute with a QName value
158          * @return a QName from an attribute's value, or null if the given attribute is null
159          */
160         static QName* getAttributeValueAsQName(const xercesc::DOMAttr* attribute);
161
162         /**
163          * Constructs a QName from a node's value.
164          *
165          * @param domNode the DOM node with a QName value
166          * @return a QName from a node's value, or null if the given node has no value
167          */
168         static QName* getNodeValueAsQName(const xercesc::DOMNode* domNode);
169
170         /**
171          * Appends the child Element to the parent Element,
172          * importing the child Element into the parent's Document if needed.
173          *
174          * @param parentElement the parent Element
175          * @param childElement the child Element
176          * @return the child Element that was added (may be an imported copy)
177          */
178         static xercesc::DOMElement* appendChildElement(xercesc::DOMElement* parentElement, xercesc::DOMElement* childElement);
179
180         /**
181          * Checks the qualified name of a node.
182          *
183          * @param n     node to check
184          * @param ns    namespace to compare with
185          * @param local local name to compare with
186          * @return  true iff the node's qualified name matches the other parameters
187          */
188         static bool isNodeNamed(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* local);
189
190         /**
191          * Returns the first matching child element of the node if any.
192          *
193          * @param n         node to check
194          * @param localName local name to compare with or NULL for any match
195          * @return  the first matching child node of type Element, or NULL
196          */
197         static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
198
199         /**
200          * Returns the last matching child element of the node if any.
201          *
202          * @param n     node to check
203          * @param localName local name to compare with or NULL for any match
204          * @return  the last matching child node of type Element, or NULL
205          */
206         static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
207
208         /**
209          * Returns the next matching sibling element of the node if any.
210          *
211          * @param n     node to check
212          * @param localName local name to compare with or NULL for any match
213          * @return  the next matching sibling node of type Element, or NULL
214          */
215         static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
216
217         /**
218          * Returns the previous matching sibling element of the node if any.
219          *
220          * @param n     node to check
221          * @param localName local name to compare with or NULL for any match
222          * @return  the previous matching sibling node of type Element, or NULL
223          */
224         static xercesc::DOMElement* getPreviousSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
225
226         /**
227          * Returns the first matching child element of the node if any.
228          *
229          * @param n         node to check
230          * @param ns        namespace to compare with
231          * @param localName local name to compare with
232          * @return  the first matching child node of type Element, or NULL
233          */
234         static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
235
236         /**
237          * Returns the last matching child element of the node if any.
238          *
239          * @param n         node to check
240          * @param ns        namespace to compare with
241          * @param localName local name to compare with
242          * @return  the last matching child node of type Element, or NULL
243          */
244         static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
245
246         /**
247          * Returns the next matching sibling element of the node if any.
248          *
249          * @param n         node to check
250          * @param ns        namespace to compare with
251          * @param localName local name to compare with
252          * @return  the next matching sibling node of type Element, or NULL
253          */
254         static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
255
256         /**
257          * Returns the previous matching sibling element of the node if any.
258          *
259          * @param n         node to check
260          * @param ns        namespace to compare with
261          * @param localName local name to compare with
262          * @return  the previous matching sibling node of type Element, or NULL
263          */
264         static xercesc::DOMElement* getPreviousSiblingElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
265
266         /**
267          * Returns the content of the first Text node found in the element, if any.
268          * This is roughly similar to the DOM getTextContent function, but only
269          * examples the immediate children of the element.
270          *
271          * @param e     element to examine
272          * @return the content of the first Text node found, or NULL
273          */
274         static const XMLCh* getTextContent(const xercesc::DOMElement* e);
275
276         /**
277          * Serializes the DOM node provided into a buffer using UTF-8 encoding and
278          * the default XML serializer available. No manipulation or formatting is applied.
279          *
280          * @param n         node to serialize
281          * @param buf       buffer to serialize element into
282          * @param pretty    enable pretty printing if supported
283          */
284         static void serialize(const xercesc::DOMNode* n, std::string& buf, bool pretty=false);
285
286         /**
287          * Serializes the DOM node provided to a stream using UTF-8 encoding and
288          * the default XML serializer available. No manipulation or formatting is applied.
289          *
290          * @param n         node to serialize
291          * @param out       stream to serialize element into
292          * @param pretty    enable pretty printing if supported
293          * @return reference to output stream
294          */
295         static std::ostream& serialize(const xercesc::DOMNode* n, std::ostream& out, bool pretty=false);
296     };
297
298     /**
299      * Serializes the DOM node provided to a stream using UTF-8 encoding and
300      * the default XML serializer available. No manipulation or formatting is applied.
301      *
302      * @param n      node to serialize
303      * @param ostr   stream to serialize element into
304      * @return reference to output stream
305      */
306     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const xercesc::DOMNode& n);
307
308     /**
309      * Marshalls and serializes the XMLObject provided to a stream using UTF-8 encoding and
310      * the default XML serializer available. No manipulation or formatting is applied.
311      *
312      * <p>The marshaller operation takes no parameters.
313      *
314      * @param obj    object to serialize
315      * @param ostr   stream to serialize object into
316      * @return reference to output stream
317      */
318     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const XMLObject& obj);
319 };
320
321 #endif /* __xmltooling_xmlhelper_h__ */