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             return (n && xercesc::XMLString::equals(local,n->getLocalName()) && xercesc::XMLString::equals(ns,n->getNamespaceURI()));
181         }
182
183         /**
184          * Returns the first matching child element of the node if any.
185          *
186          * @param n         node to check
187          * @param localName local name to compare with or NULL for any match
188          * @return  the first matching child node of type Element, or NULL
189          */
190         static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
191
192         /**
193          * Returns the last matching child element of the node if any.
194          *
195          * @param n     node to check
196          * @param localName local name to compare with or NULL for any match
197          * @return  the last matching child node of type Element, or NULL
198          */
199         static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
200
201         /**
202          * Returns the next matching sibling element of the node if any.
203          *
204          * @param n     node to check
205          * @param localName local name to compare with or NULL for any match
206          * @return  the next matching sibling node of type Element, or NULL
207          */
208         static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
209
210         /**
211          * Returns the previous matching sibling element of the node if any.
212          *
213          * @param n     node to check
214          * @param localName local name to compare with or NULL for any match
215          * @return  the previous matching sibling node of type Element, or NULL
216          */
217         static xercesc::DOMElement* getPreviousSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
218
219         /**
220          * Returns the first matching child element of the node if any.
221          *
222          * @param n         node to check
223          * @param ns        namespace to compare with
224          * @param localName local name to compare with
225          * @return  the first matching child node of type Element, or NULL
226          */
227         static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
228
229         /**
230          * Returns the last matching child element of the node if any.
231          *
232          * @param n         node to check
233          * @param ns        namespace to compare with
234          * @param localName local name to compare with
235          * @return  the last matching child node of type Element, or NULL
236          */
237         static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
238
239         /**
240          * Returns the next matching sibling element of the node if any.
241          *
242          * @param n         node to check
243          * @param ns        namespace to compare with
244          * @param localName local name to compare with
245          * @return  the next matching sibling node of type Element, or NULL
246          */
247         static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
248
249         /**
250          * Returns the previous matching sibling element of the node if any.
251          *
252          * @param n         node to check
253          * @param ns        namespace to compare with
254          * @param localName local name to compare with
255          * @return  the previous matching sibling node of type Element, or NULL
256          */
257         static xercesc::DOMElement* getPreviousSiblingElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
258
259         /**
260          * Returns the content of the first Text node found in the element, if any.
261          * This is roughly similar to the DOM getTextContent function, but only
262          * examples the immediate children of the element.
263          *
264          * @param e     element to examine
265          * @return the content of the first Text node found, or NULL
266          */
267         static const XMLCh* getTextContent(const xercesc::DOMElement* e);
268
269         /**
270          * Serializes the DOM node provided into a buffer using UTF-8 encoding and
271          * the default XML serializer available. No manipulation or formatting is applied.
272          *
273          * @param n         node to serialize
274          * @param buf       buffer to serialize element into
275          * @param pretty    enable pretty printing if supported
276          */
277         static void serialize(const xercesc::DOMNode* n, std::string& buf, bool pretty=false);
278
279         /**
280          * Serializes the DOM node provided to a stream using UTF-8 encoding and
281          * the default XML serializer available. No manipulation or formatting is applied.
282          *
283          * @param n         node to serialize
284          * @param out       stream to serialize element into
285          * @param pretty    enable pretty printing if supported
286          * @return reference to output stream
287          */
288         static std::ostream& serialize(const xercesc::DOMNode* n, std::ostream& out, bool pretty=false);
289     };
290
291     /**
292      * Serializes the DOM node provided to a stream using UTF-8 encoding and
293      * the default XML serializer available. No manipulation or formatting is applied.
294      *
295      * @param n      node to serialize
296      * @param ostr   stream to serialize element into
297      * @return reference to output stream
298      */
299     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const xercesc::DOMNode& n);
300
301     /**
302      * Marshalls and serializes the XMLObject provided to a stream using UTF-8 encoding and
303      * the default XML serializer available. No manipulation or formatting is applied.
304      *
305      * <p>The marshaller operation takes no parameters.
306      *
307      * @param obj    object to serialize
308      * @param ostr   stream to serialize object into
309      * @return reference to output stream
310      */
311     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const XMLObject& obj);
312 };
313
314 #endif /* __xmltooling_xmlhelper_h__ */