Line data Source code
1 : // file : xsd/cxx/xml/dom/parsing-source.txx
2 : // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
3 : // license : GNU GPL v2 + exceptions; see accompanying LICENSE file
4 :
5 : #include <xercesc/dom/DOMLSParser.hpp>
6 : #include <xercesc/dom/DOMLSException.hpp>
7 :
8 : #include <xercesc/dom/DOMNamedNodeMap.hpp>
9 : #include <xercesc/dom/DOMImplementation.hpp>
10 : #include <xercesc/dom/DOMImplementationRegistry.hpp>
11 :
12 : #include <xercesc/util/XMLUni.hpp> // xercesc::fg*
13 : #include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc
14 :
15 : #include <xercesc/framework/Wrapper4InputSource.hpp>
16 :
17 : #include <xsd/cxx/xml/string.hxx>
18 : #include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
19 :
20 : namespace xsd
21 : {
22 : namespace cxx
23 : {
24 : namespace xml
25 : {
26 : namespace dom
27 : {
28 : // parser
29 : //
30 : template <typename C>
31 0 : parser<C>::
32 : parser (const xercesc::DOMElement& e, bool ep, bool tp, bool ap)
33 0 : : element_ (e),
34 0 : next_content_ (0),
35 0 : a_ (0),
36 0 : ai_ (0)
37 : {
38 : using xercesc::DOMNode;
39 :
40 0 : if (ep)
41 : {
42 0 : for (next_content_ = e.getFirstChild ();;
43 0 : next_content_ = next_content_->getNextSibling ())
44 : {
45 0 : if (next_content_ == 0)
46 0 : break;
47 :
48 0 : DOMNode::NodeType t (next_content_->getNodeType ());
49 :
50 0 : if (t == DOMNode::ELEMENT_NODE)
51 0 : break;
52 :
53 0 : if (tp && (t == DOMNode::TEXT_NODE ||
54 : t == DOMNode::CDATA_SECTION_NODE))
55 : break;
56 : }
57 : }
58 :
59 0 : if (ap)
60 : {
61 0 : a_ = e.getAttributes ();
62 0 : as_ = a_->getLength ();
63 : }
64 0 : }
65 :
66 : template <typename C>
67 0 : void parser<C>::
68 : next_content (bool tp)
69 : {
70 : using xercesc::DOMNode;
71 :
72 0 : for (next_content_ = next_content_->getNextSibling ();;
73 0 : next_content_ = next_content_->getNextSibling ())
74 : {
75 0 : if (next_content_ == 0)
76 0 : break;
77 :
78 0 : DOMNode::NodeType t (next_content_->getNodeType ());
79 :
80 0 : if (t == DOMNode::ELEMENT_NODE)
81 0 : break;
82 :
83 0 : if (tp && (t == DOMNode::TEXT_NODE ||
84 : t == DOMNode::CDATA_SECTION_NODE))
85 : break;
86 : }
87 0 : }
88 :
89 : // parse()
90 : //
91 : template <typename C>
92 : XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
93 0 : parse (xercesc::InputSource& is,
94 : error_handler<C>& eh,
95 : const properties<C>& prop,
96 : unsigned long flags)
97 : {
98 0 : bits::error_handler_proxy<C> ehp (eh);
99 0 : return xml::dom::parse (is, ehp, prop, flags);
100 0 : }
101 :
102 : template <typename C>
103 : XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
104 0 : parse (xercesc::InputSource& is,
105 : xercesc::DOMErrorHandler& eh,
106 : const properties<C>& prop,
107 : unsigned long flags)
108 : {
109 : using namespace xercesc;
110 :
111 : // Instantiate the DOM parser.
112 : //
113 0 : const XMLCh ls_id[] = {xercesc::chLatin_L,
114 : xercesc::chLatin_S,
115 : xercesc::chNull};
116 :
117 : // Get an implementation of the Load-Store (LS) interface.
118 : //
119 : DOMImplementation* impl (
120 0 : DOMImplementationRegistry::getDOMImplementation (ls_id));
121 :
122 0 : XSD_DOM_AUTO_PTR<DOMLSParser> parser (
123 0 : impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
124 :
125 0 : DOMConfiguration* conf (parser->getDomConfig ());
126 :
127 : // Discard comment nodes in the document.
128 : //
129 0 : conf->setParameter (XMLUni::fgDOMComments, false);
130 :
131 : // Enable datatype normalization.
132 : //
133 0 : conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
134 :
135 : // Do not create EntityReference nodes in the DOM tree. No
136 : // EntityReference nodes will be created, only the nodes
137 : // corresponding to their fully expanded substitution text
138 : // will be created.
139 : //
140 0 : conf->setParameter (XMLUni::fgDOMEntities, false);
141 :
142 : // Perform namespace processing.
143 : //
144 0 : conf->setParameter (XMLUni::fgDOMNamespaces, true);
145 :
146 : // Do not include ignorable whitespace in the DOM tree.
147 : //
148 0 : conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
149 :
150 0 : if (flags & dont_validate)
151 : {
152 0 : conf->setParameter (XMLUni::fgDOMValidate, false);
153 0 : conf->setParameter (XMLUni::fgXercesSchema, false);
154 0 : conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
155 : }
156 : else
157 : {
158 0 : conf->setParameter (XMLUni::fgDOMValidate, true);
159 0 : conf->setParameter (XMLUni::fgXercesSchema, true);
160 :
161 : // Xerces-C++ 3.1.0 is the first version with working multi import
162 : // support.
163 : //
164 : #if _XERCES_VERSION >= 30100
165 0 : if (!(flags & no_muliple_imports))
166 0 : conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
167 : #endif
168 : // This feature checks the schema grammar for additional
169 : // errors. We most likely do not need it when validating
170 : // instances (assuming the schema is valid).
171 : //
172 0 : conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
173 : }
174 :
175 : // We will release DOM ourselves.
176 : //
177 0 : conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
178 :
179 :
180 : // Transfer properies if any.
181 : //
182 :
183 0 : if (!prop.schema_location ().empty ())
184 : {
185 0 : xml::string sl (prop.schema_location ());
186 0 : const void* v (sl.c_str ());
187 :
188 0 : conf->setParameter (
189 : XMLUni::fgXercesSchemaExternalSchemaLocation,
190 : const_cast<void*> (v));
191 0 : }
192 :
193 0 : if (!prop.no_namespace_schema_location ().empty ())
194 : {
195 0 : xml::string sl (prop.no_namespace_schema_location ());
196 0 : const void* v (sl.c_str ());
197 :
198 0 : conf->setParameter (
199 : XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
200 : const_cast<void*> (v));
201 0 : }
202 :
203 : // If external schema location was specified, disable loading
204 : // schemas via the schema location attributes in the document.
205 : //
206 : #if _XERCES_VERSION >= 30100
207 0 : if (!prop.schema_location ().empty () ||
208 0 : !prop.no_namespace_schema_location ().empty ())
209 : {
210 0 : conf->setParameter (XMLUni::fgXercesLoadSchema, false);
211 : }
212 : #endif
213 : // Set error handler.
214 : //
215 0 : bits::error_handler_proxy<C> ehp (eh);
216 0 : conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
217 :
218 0 : xercesc::Wrapper4InputSource wrap (&is, false);
219 :
220 0 : XSD_DOM_AUTO_PTR<DOMDocument> doc;
221 : try
222 : {
223 0 : doc.reset (parser->parse (&wrap));
224 : }
225 0 : catch (const xercesc::DOMLSException&)
226 : {
227 : }
228 :
229 0 : if (ehp.failed ())
230 0 : doc.reset ();
231 :
232 0 : return doc;
233 0 : }
234 :
235 : template <typename C>
236 : XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
237 0 : parse (const std::basic_string<C>& uri,
238 : error_handler<C>& eh,
239 : const properties<C>& prop,
240 : unsigned long flags)
241 : {
242 0 : bits::error_handler_proxy<C> ehp (eh);
243 0 : return xml::dom::parse (uri, ehp, prop, flags);
244 0 : }
245 :
246 : template <typename C>
247 : XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
248 0 : parse (const std::basic_string<C>& uri,
249 : xercesc::DOMErrorHandler& eh,
250 : const properties<C>& prop,
251 : unsigned long flags)
252 : {
253 : using namespace xercesc;
254 :
255 : // Instantiate the DOM parser.
256 : //
257 0 : const XMLCh ls_id[] = {xercesc::chLatin_L,
258 : xercesc::chLatin_S,
259 : xercesc::chNull};
260 :
261 : // Get an implementation of the Load-Store (LS) interface.
262 : //
263 : DOMImplementation* impl (
264 0 : DOMImplementationRegistry::getDOMImplementation (ls_id));
265 :
266 0 : XSD_DOM_AUTO_PTR<DOMLSParser> parser (
267 0 : impl->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
268 :
269 0 : DOMConfiguration* conf (parser->getDomConfig ());
270 :
271 : // Discard comment nodes in the document.
272 : //
273 0 : conf->setParameter (XMLUni::fgDOMComments, false);
274 :
275 : // Enable datatype normalization.
276 : //
277 0 : conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
278 :
279 : // Do not create EntityReference nodes in the DOM tree. No
280 : // EntityReference nodes will be created, only the nodes
281 : // corresponding to their fully expanded substitution text
282 : // will be created.
283 : //
284 0 : conf->setParameter (XMLUni::fgDOMEntities, false);
285 :
286 : // Perform namespace processing.
287 : //
288 0 : conf->setParameter (XMLUni::fgDOMNamespaces, true);
289 :
290 : // Do not include ignorable whitespace in the DOM tree.
291 : //
292 0 : conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
293 :
294 0 : if (flags & dont_validate)
295 : {
296 0 : conf->setParameter (XMLUni::fgDOMValidate, false);
297 0 : conf->setParameter (XMLUni::fgXercesSchema, false);
298 0 : conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
299 : }
300 : else
301 : {
302 0 : conf->setParameter (XMLUni::fgDOMValidate, true);
303 0 : conf->setParameter (XMLUni::fgXercesSchema, true);
304 :
305 : // Xerces-C++ 3.1.0 is the first version with working multi import
306 : // support.
307 : //
308 : #if _XERCES_VERSION >= 30100
309 0 : if (!(flags & no_muliple_imports))
310 0 : conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
311 : #endif
312 :
313 : // This feature checks the schema grammar for additional
314 : // errors. We most likely do not need it when validating
315 : // instances (assuming the schema is valid).
316 : //
317 0 : conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
318 : }
319 :
320 : // We will release DOM ourselves.
321 : //
322 0 : conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
323 :
324 :
325 : // Transfer properies if any.
326 : //
327 :
328 0 : if (!prop.schema_location ().empty ())
329 : {
330 0 : xml::string sl (prop.schema_location ());
331 0 : const void* v (sl.c_str ());
332 :
333 0 : conf->setParameter (
334 : XMLUni::fgXercesSchemaExternalSchemaLocation,
335 : const_cast<void*> (v));
336 0 : }
337 :
338 0 : if (!prop.no_namespace_schema_location ().empty ())
339 : {
340 0 : xml::string sl (prop.no_namespace_schema_location ());
341 0 : const void* v (sl.c_str ());
342 :
343 0 : conf->setParameter (
344 : XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
345 : const_cast<void*> (v));
346 0 : }
347 :
348 : // If external schema location was specified, disable loading
349 : // schemas via the schema location attributes in the document.
350 : //
351 : #if _XERCES_VERSION >= 30100
352 0 : if (!prop.schema_location ().empty () ||
353 0 : !prop.no_namespace_schema_location ().empty ())
354 : {
355 0 : conf->setParameter (XMLUni::fgXercesLoadSchema, false);
356 : }
357 : #endif
358 : // Set error handler.
359 : //
360 0 : bits::error_handler_proxy<C> ehp (eh);
361 0 : conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
362 :
363 0 : XSD_DOM_AUTO_PTR<DOMDocument> doc;
364 : try
365 : {
366 0 : doc.reset (parser->parseURI (string (uri).c_str ()));
367 : }
368 0 : catch (const xercesc::DOMLSException&)
369 : {
370 : }
371 :
372 0 : if (ehp.failed ())
373 0 : doc.reset ();
374 :
375 0 : return doc;
376 0 : }
377 : }
378 : }
379 : }
380 : }
|