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