2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
22 * @file xmltooling/util/XMLHelper.h
24 * A helper class for working with W3C DOM objects.
27 #ifndef __xmltooling_xmlhelper_h__
28 #define __xmltooling_xmlhelper_h__
30 #include <xmltooling/unicode.h>
34 #include <xercesc/dom/DOM.hpp>
36 namespace xmltooling {
38 class XMLTOOL_API QName;
39 class XMLTOOL_API XMLObject;
42 * RAII wrapper for Xerces resources.
44 template<class T> class XercesJanitor
46 MAKE_NONCOPYABLE(XercesJanitor);
52 * @param resource object to release when leaving scope
54 XercesJanitor(T* resource) : m_held(resource) {}
62 * Returns resource held by this object.
64 * @return the resource held or nullptr
71 * Returns resource held by this object.
73 * @return the resource held or nullptr
80 * Returns resource held by this object and releases it to the caller.
82 * @return the resource held or nullptr
92 * A helper class for working with W3C DOM objects.
94 class XMLTOOL_API XMLHelper
98 * Checks if the given element has an xsi:type defined for it
100 * @param e the DOM element
101 * @return true if there is a type, false if not
103 static bool hasXSIType(const xercesc::DOMElement* e);
106 * Gets the XSI type for a given element if it has one.
107 * <p>The caller is responsible for freeing the result.
109 * @param e the element
110 * @return the type or null
112 static QName* getXSIType(const xercesc::DOMElement* e);
115 * Gets the ID attribute of a DOM element.
117 * @param domElement the DOM element
118 * @return the ID attribute or null if there isn't one
120 static xercesc::DOMAttr* getIdAttribute(const xercesc::DOMElement* domElement);
123 * Attempts to locate an XMLObject from this point downward in the tree whose
124 * XML ID matches the supplied value.
126 * @param tree root of tree to search
127 * @param id ID value to locate
128 * @return XMLObject in the tree with a matching ID value, or nullptr
130 static const XMLObject* getXMLObjectById(const XMLObject& tree, const XMLCh* id);
133 * Attempts to locate an XMLObject from this point downward in the tree whose
134 * XML ID matches the supplied value.
136 * @param tree root of tree to search
137 * @param id ID value to locate
138 * @return XMLObject in the tree with a matching ID value, or nullptr
140 static XMLObject* getXMLObjectById(XMLObject& tree, const XMLCh* id);
143 * Returns the set of non-visibly-used namespace declarations found in a tree.
144 * <p>Each member of the set is a prefix/URI pair.
146 * @param tree root of tree to search
147 * @param prefixes container to store declarations
149 static void getNonVisiblyUsedPrefixes(const XMLObject& tree, std::map<xstring,xstring>& prefixes);
152 * Gets the QName for the given DOM node.
154 * @param domNode the DOM node
155 * @return the QName for the element or null if the element was null
157 static QName* getNodeQName(const xercesc::DOMNode* domNode);
161 * Constructs a QName from an attribute's value.
162 * <p>The caller is responsible for freeing the result.
164 * @param attribute the attribute with a QName value
165 * @return a QName from an attribute's value, or null if the given attribute is null
167 static QName* getAttributeValueAsQName(const xercesc::DOMAttr* attribute);
170 * Constructs a QName from a node's value.
171 * <p>The caller is responsible for freeing the result.
173 * @param domNode the DOM node with a QName value
174 * @return a QName from a node's value, or null if the given node has no value
176 static QName* getNodeValueAsQName(const xercesc::DOMNode* domNode);
179 * Returns a boolean based on a node's value.
181 * @param domNode the DOM node with a boolean (1/0/true/false) value
182 * @param def value to return if the node is null/missing
183 * @return a bool value based on the node's value, or a default value
185 static bool getNodeValueAsBool(const xercesc::DOMNode* domNode, bool def);
188 * Appends the child Element to the parent Element,
189 * importing the child Element into the parent's Document if needed.
191 * @param parentElement the parent Element
192 * @param childElement the child Element
193 * @return the child Element that was added (may be an imported copy)
195 static xercesc::DOMElement* appendChildElement(xercesc::DOMElement* parentElement, xercesc::DOMElement* childElement);
198 * Checks the qualified name of a node.
200 * @param n node to check
201 * @param ns namespace to compare with
202 * @param local local name to compare with
203 * @return true iff the node's qualified name matches the other parameters
205 static bool isNodeNamed(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* local);
208 * Returns the first matching child element of the node if any.
210 * @param n node to check
211 * @param localName local name to compare with or nullptr for any match
212 * @return the first matching child node of type Element, or nullptr
214 static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* localName=nullptr);
217 * Returns the last matching child element of the node if any.
219 * @param n node to check
220 * @param localName local name to compare with or nullptr for any match
221 * @return the last matching child node of type Element, or nullptr
223 static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* localName=nullptr);
226 * Returns the next matching sibling element of the node if any.
228 * @param n node to check
229 * @param localName local name to compare with or nullptr for any match
230 * @return the next matching sibling node of type Element, or nullptr
232 static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=nullptr);
235 * Returns the previous matching sibling element of the node if any.
237 * @param n node to check
238 * @param localName local name to compare with or nullptr for any match
239 * @return the previous matching sibling node of type Element, or nullptr
241 static xercesc::DOMElement* getPreviousSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=nullptr);
244 * Returns the first matching child element of the node if any.
246 * @param n node to check
247 * @param ns namespace to compare with
248 * @param localName local name to compare with
249 * @return the first matching child node of type Element, or nullptr
251 static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
254 * Returns the last matching child element of the node if any.
256 * @param n node to check
257 * @param ns namespace to compare with
258 * @param localName local name to compare with
259 * @return the last matching child node of type Element, or nullptr
261 static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
264 * Returns the next matching sibling element of the node if any.
266 * @param n node to check
267 * @param ns namespace to compare with
268 * @param localName local name to compare with
269 * @return the next matching sibling node of type Element, or nullptr
271 static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
274 * Returns the previous matching sibling element of the node if any.
276 * @param n node to check
277 * @param ns namespace to compare with
278 * @param localName local name to compare with
279 * @return the previous matching sibling node of type Element, or nullptr
281 static xercesc::DOMElement* getPreviousSiblingElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
284 * Returns the content of the first Text node found in the element, if any.
285 * This is roughly similar to the DOM getTextContent function, but only
286 * examines the immediate children of the element.
288 * @param e element to examine
289 * @return the content of the first Text node found, or nullptr
291 static const XMLCh* getTextContent(const xercesc::DOMElement* e);
294 * Returns the content of the specified attribute node as a string,
295 * or the default value, if the attribute is not present.
297 * @param e element to examine (may be nullptr)
298 * @param defValue default value to return
299 * @param localName local name of attribute
300 * @param ns namespace of attribute
301 * @return the specified attribute's value, or the specified default
303 static std::string getAttrString(
304 const xercesc::DOMElement* e, const char* defValue, const XMLCh* localName, const XMLCh* ns=nullptr
308 * Returns the content of the specified attribute node as an integer,
309 * or the default value, if the attribute is not present.
311 * @param e element to examine (may be nullptr)
312 * @param defValue default value to return
313 * @param localName local name of attribute
314 * @param ns namespace of attribute
315 * @return the specified attribute's value, or the specified default
317 static int getAttrInt(
318 const xercesc::DOMElement* e, int defValue, const XMLCh* localName, const XMLCh* ns=nullptr
322 * Returns the content of the specified attribute node as a boolean,
323 * or the default value, if the attribute is not present.
325 * @param e element to examine (may be nullptr)
326 * @param defValue default value to return
327 * @param localName local name of attribute
328 * @param ns namespace of attribute
329 * @return the specified attribute's value, or the specified default
331 static bool getAttrBool(
332 const xercesc::DOMElement* e, bool defValue, const XMLCh* localName, const XMLCh* ns=nullptr
336 * Serializes the DOM node provided into a buffer using UTF-8 encoding and
337 * the default XML serializer available. No manipulation or formatting is applied.
339 * @param n node to serialize
340 * @param buf buffer to serialize element into
341 * @param pretty enable pretty printing if supported
343 static void serialize(const xercesc::DOMNode* n, std::string& buf, bool pretty=false);
346 * Serializes the DOM node provided to a stream using UTF-8 encoding and
347 * the default XML serializer available. No manipulation or formatting is applied.
349 * @param n node to serialize
350 * @param out stream to serialize element into
351 * @param pretty enable pretty printing if supported
352 * @return reference to output stream
354 static std::ostream& serialize(const xercesc::DOMNode* n, std::ostream& out, bool pretty=false);
358 * Serializes the DOM node provided to a stream using UTF-8 encoding and
359 * the default XML serializer available. No manipulation or formatting is applied.
361 * @param n node to serialize
362 * @param ostr stream to serialize element into
363 * @return reference to output stream
365 extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const xercesc::DOMNode& n);
368 * Marshalls and serializes the XMLObject provided to a stream using UTF-8 encoding and
369 * the default XML serializer available. No manipulation or formatting is applied.
371 * <p>The marshaller operation takes no parameters.
373 * @param obj object to serialize
374 * @param ostr stream to serialize object into
375 * @return reference to output stream
377 extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const XMLObject& obj);
380 #endif /* __xmltooling_xmlhelper_h__ */