]> git.donarmstrong.com Git - flightcrew.git/blob - src/XercesExtensions/XmlUtils.cpp
Imported Upstream version 0.7.2+dfsg
[flightcrew.git] / src / XercesExtensions / XmlUtils.cpp
1 /************************************************************************\r
2 **\r
3 **  Copyright (C) 2010  Strahinja Markovic\r
4 **\r
5 **  This file is part of FlightCrew.\r
6 **\r
7 **  FlightCrew is free software: you can redistribute it and/or modify\r
8 **  it under the terms of the GNU Lesser General Public License as published\r
9 **  by the Free Software Foundation, either version 3 of the License, or\r
10 **  (at your option) any later version.\r
11 **\r
12 **  FlightCrew is distributed in the hope that it will be useful,\r
13 **  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 **  GNU Lesser General Public License for more details.\r
16 **\r
17 **  You should have received a copy of the GNU Lesser General Public License\r
18 **  along with FlightCrew.  If not, see <http://www.gnu.org/licenses/>.\r
19 **\r
20 *************************************************************************/\r
21 \r
22 #include "XmlUtils.h"\r
23 #include "ToXercesStringConverter.h"\r
24 #include "FromXercesStringConverter.h"\r
25 #include <xercesc/dom/DOMElement.hpp>\r
26 #include <xercesc/dom/DOMAttr.hpp>\r
27 #include <xercesc/dom/DOMDocument.hpp>\r
28 #include <xercesc/dom/DOMNodeList.hpp>\r
29 #include <xercesc/dom/DOMNamedNodeMap.hpp>\r
30 #include <boost/foreach.hpp> \r
31 #define foreach BOOST_FOREACH\r
32 \r
33 extern const char *LOCATION_INFO_KEY;\r
34 \r
35 typedef unsigned int uint;\r
36 \r
37 namespace XercesExt\r
38 {\r
39 \r
40 NodeLocationInfo GetNodeLocationInfo( const xc::DOMNode &node )\r
41 {\r
42     NodeLocationInfo *location = static_cast< NodeLocationInfo* >(\r
43         node.getUserData( toX( LOCATION_INFO_KEY ) ) );\r
44 \r
45     if ( location )\r
46 \r
47         return *location;\r
48     \r
49     return NodeLocationInfo();\r
50 }\r
51 \r
52 \r
53 XercesExt::NodeLocationInfo GetNearestNodeLocationInfo( const xc::DOMNode &node )\r
54 {\r
55     const xc::DOMNode *current_node = &node;\r
56     NodeLocationInfo location;\r
57 \r
58     while ( true )\r
59     {\r
60         location = GetNodeLocationInfo( *current_node );\r
61 \r
62         if ( location.LineNumber != -1 )\r
63         {\r
64             break;                        \r
65         }\r
66 \r
67         else\r
68         {\r
69             current_node = current_node->getParentNode();\r
70 \r
71             if ( !current_node )\r
72 \r
73                 break;   \r
74         }        \r
75     }\r
76 \r
77     return location;\r
78 }\r
79 \r
80 \r
81 std::vector< xc::DOMElement* > GetElementsByQName( const xc::DOMElement &start_element, \r
82                                                    const QName &element_qname )\r
83 {\r
84     xc::DOMNodeList *elements = start_element.getElementsByTagNameNS(\r
85         toX( element_qname.namespace_name ),  toX( element_qname.local_name ) );\r
86 \r
87     return ExtractElementsFromNodeList( *elements );\r
88 }\r
89 \r
90 \r
91 std::vector< xc::DOMElement* > GetElementsByQName( const xc::DOMDocument &document, \r
92                                                    const QName &element_qname )\r
93 {\r
94     xc::DOMNodeList *elements = document.getElementsByTagNameNS(\r
95         toX( element_qname.namespace_name ),  toX( element_qname.local_name ) );\r
96 \r
97     return ExtractElementsFromNodeList( *elements );\r
98 }\r
99 \r
100 \r
101 std::vector< xc::DOMElement* > GetElementChildren( const xc::DOMElement &element )\r
102 {\r
103     xc::DOMElement *child = element.getFirstElementChild();\r
104 \r
105     std::vector< xc::DOMElement* > children;\r
106 \r
107     if ( !child )\r
108 \r
109         return children;\r
110 \r
111     children.push_back( child );\r
112 \r
113     while (true)\r
114     {\r
115          child = child->getNextElementSibling();\r
116 \r
117          if ( !child )\r
118 \r
119              return children;\r
120          \r
121          children.push_back( child );\r
122     }\r
123 }\r
124 \r
125 \r
126 std::vector< xc::DOMAttr* > GetAllAttributesFromElements( const QName &element_qname, \r
127                                                           const QName &attribute_qname,\r
128                                                           const xc::DOMDocument &document )\r
129 {\r
130     xc::DOMNodeList *elements = document.getElementsByTagNameNS(\r
131         toX( element_qname.namespace_name ),  toX( element_qname.local_name ) );\r
132 \r
133     std::vector< xc::DOMAttr* > attributes;\r
134 \r
135     for ( uint i = 0; i < elements->getLength(); ++i )\r
136     {\r
137         xc::DOMNamedNodeMap *attribute_map = elements->item( i )->getAttributes();\r
138 \r
139         if ( !attribute_map )\r
140 \r
141             continue;\r
142 \r
143         for ( uint j = 0; j < attribute_map->getLength(); ++j )\r
144         {\r
145             xc::DOMAttr *attribute = static_cast< xc::DOMAttr* >( attribute_map->item( j ) );\r
146             QName current_attribute_qname( fromX( attribute->getLocalName() ),\r
147                                            fromX( attribute->getNamespaceURI() ) );\r
148 \r
149             if ( attribute_qname == current_attribute_qname )\r
150 \r
151                 attributes.push_back( attribute );\r
152         }\r
153     }\r
154 \r
155     return attributes;\r
156 }\r
157 \r
158 \r
159 std::vector< xc::DOMElement* > ExtractElementsFromNodeList( const xc::DOMNodeList &node_list )\r
160 {\r
161     std::vector< xc::DOMElement* > element_list;\r
162 \r
163     for ( uint i = 0; i < node_list.getLength(); ++i )\r
164     {\r
165         xc::DOMNode *node = node_list.item( i );\r
166 \r
167         if ( node->getNodeType() == xc::DOMNode::ELEMENT_NODE )\r
168 \r
169             element_list.push_back( static_cast< xc::DOMElement* >( node ) );\r
170     }\r
171 \r
172     return element_list;\r
173 }\r
174 \r
175 \r
176 bool ElementListContains( std::vector< xc::DOMElement* > element_list,\r
177                           const QName &element_qname )\r
178 {\r
179     for ( uint i = 0; i < element_list.size(); ++i )\r
180     {\r
181         xc::DOMElement *element = element_list[ i ];\r
182         QName current_qname( fromX( element->getLocalName() ), \r
183                              fromX( element->getNamespaceURI() ) );\r
184 \r
185         if ( current_qname == element_qname )\r
186         \r
187             return true;\r
188     } \r
189 \r
190     return false;\r
191 }\r
192 \r
193 xc::DOMNode* GetFirstAvailableElement( const std::vector< QName > &element_qnames,\r
194                                        const xc::DOMDocument &document )\r
195 {\r
196     foreach( QName element_qname, element_qnames )\r
197     {\r
198         xc::DOMNodeList *matching_nodes = document.getElementsByTagNameNS(\r
199                toX( element_qname.namespace_name ),  toX( element_qname.local_name ) );\r
200 \r
201         if ( matching_nodes->getLength() > 0 )\r
202 \r
203             return matching_nodes->item( 0 );\r
204     }\r
205 \r
206     return NULL;\r
207 }\r
208 \r
209 xc::DOMNode* GetFirstAvailableElement( const QName &element_qname, \r
210                                        const xc::DOMDocument &document )\r
211 {\r
212     std::vector< QName > element_qnames;\r
213     element_qnames.push_back( element_qname );\r
214 \r
215     return GetFirstAvailableElement( element_qnames, document );\r
216 }\r
217 \r
218 \r
219 void XercesStringDeallocator( XMLCh *xstring )\r
220 {\r
221     xc::XMLString::release( &xstring );\r
222 }\r
223 \r
224 \r
225 \r
226 } // namespace XercesExt\r