Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 Ericsson Telecom AB | |
3 | // All rights reserved. This program and the accompanying materials | |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | /* | |
9 | * XmlReader.cc | |
10 | * | |
11 | * Created on: 19-Nov-2008 | |
12 | * Author: ecsardu | |
13 | */ | |
14 | ||
15 | #include <libxml/xmlreader.h> | |
16 | #include "XmlReader.hh" | |
17 | #include "static_check.h" | |
18 | ||
19 | #include "Encdec.hh" | |
20 | ||
21 | XmlReaderWrap::XmlReaderWrap(TTCN_Buffer& buf) | |
22 | : my_reader(0) | |
23 | { | |
24 | // compile-time safety checks | |
25 | ENSURE_EQUAL( XML_PARSER_SEVERITY_VALIDITY_WARNING, \ | |
26 | xmlreader_lite::XML_PARSER_SEVERITY_VALIDITY_WARNING); | |
27 | ENSURE_EQUAL( XML_PARSER_SEVERITY_VALIDITY_ERROR , \ | |
28 | xmlreader_lite::XML_PARSER_SEVERITY_VALIDITY_ERROR); | |
29 | ENSURE_EQUAL( XML_PARSER_SEVERITY_WARNING, \ | |
30 | xmlreader_lite::XML_PARSER_SEVERITY_WARNING); | |
31 | ENSURE_EQUAL( XML_PARSER_SEVERITY_ERROR , \ | |
32 | xmlreader_lite::XML_PARSER_SEVERITY_ERROR); | |
33 | ||
34 | ENSURE_EQUAL( XML_READER_TYPE_NONE, \ | |
35 | xmlreader_lite::XML_READER_TYPE_NONE); | |
36 | ENSURE_EQUAL( XML_READER_TYPE_ELEMENT, \ | |
37 | xmlreader_lite::XML_READER_TYPE_ELEMENT); | |
38 | ENSURE_EQUAL( XML_READER_TYPE_ATTRIBUTE, \ | |
39 | xmlreader_lite::XML_READER_TYPE_ATTRIBUTE); | |
40 | ENSURE_EQUAL( XML_READER_TYPE_TEXT, \ | |
41 | xmlreader_lite::XML_READER_TYPE_TEXT); | |
42 | ENSURE_EQUAL( XML_READER_TYPE_CDATA, \ | |
43 | xmlreader_lite::XML_READER_TYPE_CDATA); | |
44 | ENSURE_EQUAL( XML_READER_TYPE_ENTITY_REFERENCE, \ | |
45 | xmlreader_lite::XML_READER_TYPE_ENTITY_REFERENCE); | |
46 | ENSURE_EQUAL( XML_READER_TYPE_ENTITY, \ | |
47 | xmlreader_lite::XML_READER_TYPE_ENTITY); | |
48 | ENSURE_EQUAL( XML_READER_TYPE_PROCESSING_INSTRUCTION, \ | |
49 | xmlreader_lite::XML_READER_TYPE_PROCESSING_INSTRUCTION); | |
50 | ENSURE_EQUAL( XML_READER_TYPE_COMMENT, \ | |
51 | xmlreader_lite::XML_READER_TYPE_COMMENT); | |
52 | ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT, \ | |
53 | xmlreader_lite::XML_READER_TYPE_DOCUMENT); | |
54 | ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT_TYPE, \ | |
55 | xmlreader_lite::XML_READER_TYPE_DOCUMENT_TYPE); | |
56 | ENSURE_EQUAL( XML_READER_TYPE_DOCUMENT_FRAGMENT, \ | |
57 | xmlreader_lite::XML_READER_TYPE_DOCUMENT_FRAGMENT); | |
58 | ENSURE_EQUAL( XML_READER_TYPE_NOTATION, \ | |
59 | xmlreader_lite::XML_READER_TYPE_NOTATION); | |
60 | ENSURE_EQUAL( XML_READER_TYPE_WHITESPACE, \ | |
61 | xmlreader_lite::XML_READER_TYPE_WHITESPACE); | |
62 | ENSURE_EQUAL( XML_READER_TYPE_SIGNIFICANT_WHITESPACE, \ | |
63 | xmlreader_lite::XML_READER_TYPE_SIGNIFICANT_WHITESPACE); | |
64 | ENSURE_EQUAL( XML_READER_TYPE_END_ELEMENT, \ | |
65 | xmlreader_lite::XML_READER_TYPE_END_ELEMENT); | |
66 | ENSURE_EQUAL( XML_READER_TYPE_END_ENTITY, \ | |
67 | xmlreader_lite::XML_READER_TYPE_END_ENTITY); | |
68 | ENSURE_EQUAL( XML_READER_TYPE_XML_DECLARATION, \ | |
69 | xmlreader_lite::XML_READER_TYPE_XML_DECLARATION); | |
70 | ||
71 | LIBXML_TEST_VERSION; | |
72 | const char * encoding = 0; | |
73 | if (0 == buf.get_len()) { | |
74 | TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG, | |
75 | "Cannot decode empty XML"); | |
76 | } | |
77 | else { | |
78 | my_reader = xmlReaderForMemory((const char*)buf.get_data(), buf.get_len(), | |
79 | "uri:geller", encoding, 0); | |
80 | if (0 == my_reader) { | |
81 | TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, | |
82 | "Failed to create XML reader"); // no further information available | |
83 | } | |
84 | else xmlTextReaderSetErrorHandler(my_reader, errorhandler, this); | |
85 | } | |
86 | } | |
87 | ||
88 | void | |
89 | XmlReaderWrap::errorhandler(void * arg, const char * msg, | |
90 | xmlParserSeverities severity, xmlTextReaderLocatorPtr locator) | |
91 | { | |
92 | //XmlReaderWrap *self = (XmlReaderWrap*)arg; | |
93 | (void)arg; | |
94 | (void)severity; | |
95 | TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNDEF, // TODO create a new ET_ | |
96 | "XML error: %s at line %d", msg, xmlTextReaderLocatorLineNumber(locator)); | |
97 | } | |
98 | ||
99 | XmlReaderWrap::~XmlReaderWrap() | |
100 | { | |
101 | xmlFreeTextReader(my_reader); | |
102 | my_reader = 0; | |
103 | } | |
104 | ||
105 | ||
106 | #undef Read | |
107 | int XmlReaderWrap::Read() | |
108 | { | |
109 | return last_status = xmlTextReaderRead(my_reader); // assign and return | |
110 | } | |
111 | ||
112 | // Debug version of Read(). Both are present to support linking | |
113 | // non-debug clients to the debug library. | |
114 | int XmlReaderWrap::ReadDbg(const char *where) | |
115 | { | |
116 | #ifdef NDEBUG | |
117 | (void)where; | |
118 | #else | |
119 | static bool d = !!getenv("DEBUG_XMLREADER"); | |
120 | if(d){ | |
121 | last_status = xmlTextReaderRead(my_reader); | |
122 | if (last_status==1) { | |
123 | int type = NodeType(); | |
124 | const char * name = (const char * )Name(); | |
125 | const char * uri = (const char * )NamespaceUri(); | |
126 | int empty = IsEmptyElement(); | |
127 | char closer = type == XML_READER_TYPE_DOCUMENT_TYPE ? '[' : (empty ? '/' : ' '); | |
128 | printf("X%dX type=%2d, @%2d <%c{%s}%s%c>", | |
129 | xmlTextReaderReadState(my_reader), type, xmlTextReaderDepth(my_reader), | |
130 | ((type!=XML_READER_TYPE_END_ELEMENT) ? ' ' : '/'), | |
131 | uri ? uri : "", name, closer); | |
132 | } | |
133 | else if (last_status==0) { | |
134 | fputs("XXX eof ", stdout); | |
135 | } | |
136 | else { | |
137 | fputs("XXX error", stdout); | |
138 | } | |
139 | printf("\t%s\n", where); | |
140 | fflush(stdout); | |
141 | return last_status; | |
142 | } else | |
143 | #endif | |
144 | { | |
145 | return last_status = xmlTextReaderRead(my_reader); // assign and return | |
146 | } | |
147 | } | |
148 | ||
149 | #if 0 | |
150 | xmlChar * XmlReaderWrap::ReadInnerXml() | |
151 | { return xmlTextReaderReadInnerXml(my_reader); } | |
152 | #endif | |
153 | ||
154 | xmlChar * XmlReaderWrap::ReadOuterXml() // used by Charstring.cc | |
155 | { return xmlTextReaderReadOuterXml(my_reader); } | |
156 | ||
157 | xmlChar * XmlReaderWrap::ReadString() // used by Objid.cc | |
158 | { return xmlTextReaderReadString(my_reader); } | |
159 | ||
160 | int XmlReaderWrap::Depth() // used everywhere | |
161 | { return xmlTextReaderDepth(my_reader); } | |
162 | ||
163 | #if 0 | |
164 | int XmlReaderWrap::ReadAttributeValue() | |
165 | { return xmlTextReaderReadAttributeValue(my_reader); } | |
166 | ||
167 | int XmlReaderWrap::AttributeCount() | |
168 | { return xmlTextReaderAttributeCount(my_reader); } | |
169 | ||
170 | int XmlReaderWrap::HasAttributes() | |
171 | { return xmlTextReaderHasAttributes(my_reader); } | |
172 | ||
173 | int XmlReaderWrap::HasValue() | |
174 | { return xmlTextReaderHasValue(my_reader); } | |
175 | ||
176 | int XmlReaderWrap::IsDefault() | |
177 | { return xmlTextReaderIsDefault(my_reader); } | |
178 | #endif | |
179 | ||
180 | int XmlReaderWrap::IsEmptyElement() // used often | |
181 | { return xmlTextReaderIsEmptyElement(my_reader); } | |
182 | ||
183 | int XmlReaderWrap::NodeType() | |
184 | { return xmlTextReaderNodeType(my_reader); } | |
185 | ||
186 | #if 0 | |
187 | int XmlReaderWrap::QuoteChar() | |
188 | { return xmlTextReaderQuoteChar(my_reader); } | |
189 | ||
190 | int XmlReaderWrap::ReadState() | |
191 | { return xmlTextReaderReadState(my_reader); } | |
192 | #endif | |
193 | ||
194 | int XmlReaderWrap::IsNamespaceDecl() // used while processing attributes | |
195 | { return xmlTextReaderIsNamespaceDecl(my_reader); } | |
196 | ||
197 | #if 0 | |
198 | const xmlChar * XmlReaderWrap::BaseUri() | |
199 | { return xmlTextReaderConstBaseUri(my_reader); } | |
200 | #endif | |
201 | ||
202 | const xmlChar * XmlReaderWrap::LocalName() | |
203 | { return xmlTextReaderConstLocalName(my_reader); } | |
204 | ||
205 | const xmlChar * XmlReaderWrap::Name() | |
206 | { return xmlTextReaderConstName(my_reader); } | |
207 | ||
208 | const xmlChar * XmlReaderWrap::NamespaceUri() | |
209 | { return xmlTextReaderConstNamespaceUri(my_reader); } | |
210 | ||
211 | const xmlChar * XmlReaderWrap::Prefix() | |
212 | { return xmlTextReaderConstPrefix(my_reader); } | |
213 | ||
214 | #if 0 | |
215 | const xmlChar * XmlReaderWrap::XmlLang() | |
216 | { return xmlTextReaderConstXmlLang(my_reader); } | |
217 | #endif | |
218 | ||
219 | const xmlChar * XmlReaderWrap::Value() | |
220 | { return xmlTextReaderConstValue(my_reader); } | |
221 | ||
222 | xmlChar * XmlReaderWrap::NewValue() | |
223 | { return xmlTextReaderValue(my_reader); } | |
224 | ||
225 | xmlChar * XmlReaderWrap::LookupNamespace( const xmlChar *prefix) | |
226 | { return xmlTextReaderLookupNamespace(my_reader,prefix); } | |
227 | ||
228 | #if 0 | |
229 | int XmlReaderWrap::Close() | |
230 | { return xmlTextReaderClose(my_reader); } | |
231 | ||
232 | xmlChar * XmlReaderWrap::GetAttributeNo( int no) | |
233 | { return xmlTextReaderGetAttributeNo(my_reader,no); } | |
234 | ||
235 | xmlChar * XmlReaderWrap::GetAttribute( const xmlChar *name) | |
236 | { return xmlTextReaderGetAttribute(my_reader,name); } | |
237 | ||
238 | xmlChar * XmlReaderWrap::GetAttributeNs( const xmlChar *localName, const xmlChar *namespaceURI) | |
239 | { return xmlTextReaderGetAttributeNs(my_reader,localName,namespaceURI); } | |
240 | ||
241 | int XmlReaderWrap::MoveToAttributeNo( int no) | |
242 | { return xmlTextReaderMoveToAttributeNo(my_reader,no); } | |
243 | #endif | |
244 | ||
245 | int XmlReaderWrap::MoveToAttribute( const xmlChar *name) | |
246 | { return xmlTextReaderMoveToAttribute(my_reader,name); } | |
247 | ||
248 | //int XmlReaderWrap::MoveToAttributeNs( const xmlChar *localName, const xmlChar *namespaceURI) | |
249 | //{ return xmlTextReaderMoveToAttributeNs(my_reader,localName,namespaceURI); } | |
250 | ||
251 | #undef AdvanceAttribute | |
252 | int XmlReaderWrap::AdvanceAttribute() | |
253 | { | |
254 | int rez; | |
255 | for (rez = MoveToNextAttribute(); rez==1; rez = MoveToNextAttribute()) { | |
256 | if (!xmlTextReaderIsNamespaceDecl(my_reader)) break; | |
257 | } | |
258 | if (rez != 0) // success(1) or failure (-1) | |
259 | return rez; | |
260 | // 0 means no more attributes. Back to the element. | |
261 | rez = xmlTextReaderMoveToElement(my_reader); | |
262 | return -(rez == -1); // if -1, return -1 else return 0 | |
263 | } | |
264 | ||
265 | int XmlReaderWrap::AdvanceAttributeDbg(const char *where) | |
266 | { | |
267 | int rez; | |
268 | for (rez = MoveToNextAttributeDbg(where); rez==1; rez = MoveToNextAttributeDbg(where)) { | |
269 | if (!xmlTextReaderIsNamespaceDecl(my_reader)) break; | |
270 | } | |
271 | if (rez != 0) // success(1) or failure (-1) | |
272 | return rez; | |
273 | // 0 means no more attributes. Back to the element. | |
274 | rez = xmlTextReaderMoveToElement(my_reader); | |
275 | return -(rez == -1); // if -1, return -1 else return 0 | |
276 | } | |
277 | ||
278 | ||
279 | #undef MoveToFirstAttribute | |
280 | int XmlReaderWrap::MoveToFirstAttribute() | |
281 | { return xmlTextReaderMoveToFirstAttribute(my_reader); } | |
282 | ||
283 | int XmlReaderWrap::MoveToFirstAttributeDbg(const char *where) | |
284 | { | |
285 | int ret = xmlTextReaderMoveToFirstAttribute(my_reader); | |
286 | #ifdef NDEBUG | |
287 | (void)where; | |
288 | #else | |
289 | static bool d = !!getenv("DEBUG_XMLREADER"); | |
290 | if (d) { | |
291 | switch (ret) { | |
292 | case 1: {//OK | |
293 | const xmlChar * name = xmlTextReaderConstLocalName(my_reader); | |
294 | const xmlChar * val = xmlTextReaderConstValue(my_reader); | |
295 | printf("#%dX %s='%s'", xmlTextReaderReadState(my_reader), name, val); | |
296 | break;} | |
297 | case 0: {// not found | |
298 | const xmlChar * name = xmlTextReaderConstLocalName(my_reader); | |
299 | printf("#%dX no attribute found in <%s>", xmlTextReaderReadState(my_reader), name); | |
300 | break;} | |
301 | default: | |
302 | break; | |
303 | } | |
304 | ||
305 | printf("\t%s\n", where); | |
306 | fflush(stdout); | |
307 | } | |
308 | //return xmlTextReaderMoveToFirstAttribute(my_reader); | |
309 | #endif | |
310 | return ret; | |
311 | } | |
312 | ||
313 | #undef MoveToNextAttribute | |
314 | int XmlReaderWrap::MoveToNextAttribute() | |
315 | { return xmlTextReaderMoveToNextAttribute(my_reader); } | |
316 | ||
317 | int XmlReaderWrap::MoveToNextAttributeDbg(const char *where) | |
318 | { | |
319 | int ret = xmlTextReaderMoveToNextAttribute(my_reader); | |
320 | #ifdef NDEBUG | |
321 | (void)where; | |
322 | #else | |
323 | static bool d = !!getenv("DEBUG_XMLREADER"); | |
324 | if (d) { | |
325 | switch (ret) { | |
326 | case 1: {//OK | |
327 | const xmlChar * name = xmlTextReaderConstLocalName(my_reader); | |
328 | const xmlChar * val = xmlTextReaderConstValue(my_reader); | |
329 | printf("X%dX %s='%s'", xmlTextReaderReadState(my_reader), name, val); | |
330 | break;} | |
331 | case 0: {// not found | |
332 | const xmlChar * name = xmlTextReaderConstLocalName(my_reader); | |
333 | printf("X%dX no more attributes found after '%s'", xmlTextReaderReadState(my_reader), name); | |
334 | break;} | |
335 | default: | |
336 | break; | |
337 | } | |
338 | ||
339 | printf("\t%s\n", where); | |
340 | fflush(stdout); | |
341 | } | |
342 | //return xmlTextReaderMoveToNextAttribute(my_reader); | |
343 | #endif | |
344 | return ret; | |
345 | } | |
346 | ||
347 | #undef MoveToElement | |
348 | int XmlReaderWrap::MoveToElement() | |
349 | { return xmlTextReaderMoveToElement(my_reader); } | |
350 | ||
351 | int XmlReaderWrap::MoveToElementDbg(const char *where) | |
352 | { | |
353 | int ret = xmlTextReaderMoveToElement(my_reader); | |
354 | #ifdef NDEBUG | |
355 | (void)where; | |
356 | #else | |
357 | static bool d = !!getenv("DEBUG_XMLREADER"); | |
358 | if (d) { | |
359 | const xmlChar * name = xmlTextReaderConstLocalName(my_reader); | |
360 | const xmlChar * val = xmlTextReaderConstValue(my_reader); | |
361 | printf("X%dX <%s='%s'>\n", xmlTextReaderReadState(my_reader), name, val); | |
362 | } | |
363 | ||
364 | printf("\t%s\n", where); | |
365 | fflush(stdout); | |
366 | #endif | |
367 | return ret; | |
368 | } | |
369 | ||
370 | //int XmlReaderWrap::GetParserLineNumber() | |
371 | //{ return xmlTextReaderGetParserLineNumber(my_reader); } | |
372 | ||
373 | //int XmlReaderWrap::GetParserColumnNumber() | |
374 | //{ return xmlTextReaderGetParserColumnNumber(my_reader); } | |
375 | ||
376 | #if 0 | |
377 | int XmlReaderWrap::Next() | |
378 | { return xmlTextReaderNext(my_reader); } | |
379 | ||
380 | int XmlReaderWrap::NextSibling() | |
381 | { return xmlTextReaderNextSibling(my_reader); } | |
382 | ||
383 | int XmlReaderWrap::Normalization() | |
384 | { return xmlTextReaderNormalization(my_reader); } | |
385 | ||
386 | int XmlReaderWrap::SetParserProp( int prop, int value) | |
387 | { return xmlTextReaderSetParserProp(my_reader,prop,value); } | |
388 | ||
389 | int XmlReaderWrap::GetParserProp( int prop) | |
390 | { return xmlTextReaderGetParserProp(my_reader,prop); } | |
391 | ||
392 | xmlParserInputBufferPtr XmlReaderWrap::GetRemainder() | |
393 | { return xmlTextReaderGetRemainder(my_reader); } | |
394 | ||
395 | xmlNodePtr XmlReaderWrap::CurrentNode() | |
396 | { return xmlTextReaderCurrentNode(my_reader); } | |
397 | ||
398 | xmlNodePtr XmlReaderWrap::Preserve() | |
399 | { return xmlTextReaderPreserve(my_reader); } | |
400 | ||
401 | int XmlReaderWrap::PreservePattern( const xmlChar *pattern, const xmlChar **namespaces) | |
402 | { return xmlTextReaderPreservePattern(my_reader,pattern,namespaces); } | |
403 | ||
404 | xmlDocPtr XmlReaderWrap::CurrentDoc() | |
405 | { return xmlTextReaderCurrentDoc(my_reader); } | |
406 | ||
407 | xmlNodePtr XmlReaderWrap::Expand() | |
408 | { return xmlTextReaderExpand(my_reader); } | |
409 | ||
410 | int XmlReaderWrap::IsValid() | |
411 | { return xmlTextReaderIsValid(my_reader); } | |
412 | ||
413 | int XmlReaderWrap::RelaxNGValidate( const char *rng) | |
414 | { return xmlTextReaderRelaxNGValidate(my_reader,rng); } | |
415 | ||
416 | int XmlReaderWrap::RelaxNGSetSchema( xmlRelaxNGPtr schema) | |
417 | { return xmlTextReaderRelaxNGSetSchema(my_reader,schema); } | |
418 | ||
419 | int XmlReaderWrap::SchemaValidate( const char *xsd) | |
420 | { return xmlTextReaderSchemaValidate(my_reader,xsd); } | |
421 | ||
422 | int XmlReaderWrap::SchemaValidateCtxt( xmlSchemaValidCtxtPtr ctxt, int options) | |
423 | { return xmlTextReaderSchemaValidateCtxt(my_reader,ctxt,options); } | |
424 | ||
425 | int XmlReaderWrap::SetSchema( xmlSchemaPtr schema) | |
426 | { return xmlTextReaderSetSchema(my_reader,schema); } | |
427 | ||
428 | int XmlReaderWrap::Standalone() | |
429 | { return xmlTextReaderStandalone(my_reader); } | |
430 | #endif | |
431 | ||
432 | long XmlReaderWrap::ByteConsumed() | |
433 | { return xmlTextReaderByteConsumed(my_reader); } | |
434 | ||
435 | //int XmlReaderWrap::LocatorLineNumber(xmlTextReaderLocatorPtr locator) | |
436 | //{ return xmlTextReaderLocatorLineNumber(locator); } | |
437 | ||
438 | //xmlChar * XmlReaderWrap::LocatorBaseURI(xmlTextReaderLocatorPtr locator) | |
439 | //{ return xmlTextReaderLocatorBaseURI(locator); } | |
440 | ||
441 | #if 0 | |
442 | void XmlReaderWrap::SetErrorHandler( xmlTextReaderErrorFunc f, void *arg) | |
443 | { return xmlTextReaderSetErrorHandler(my_reader,f,arg); } | |
444 | ||
445 | void XmlReaderWrap::SetStructuredErrorHandler( xmlStructuredErrorFunc f, void *arg) | |
446 | { return xmlTextReaderSetStructuredErrorHandler(my_reader,f,arg); } | |
447 | ||
448 | void XmlReaderWrap::GetErrorHandler( xmlTextReaderErrorFunc *f, void **arg) | |
449 | { return xmlTextReaderGetErrorHandler(my_reader,f,arg); } | |
450 | #endif | |
451 | ||
452 | #ifndef NDEBUG | |
453 | void XmlReaderWrap::Status() | |
454 | { | |
455 | //const xmlChar *string = xmlTextReaderConstString (my_reader); | |
456 | const xmlChar *baseuri = xmlTextReaderConstBaseUri (my_reader); | |
457 | const xmlChar *localname= xmlTextReaderConstLocalName (my_reader); | |
458 | const xmlChar *name = xmlTextReaderConstName (my_reader); | |
459 | const xmlChar *ns_uri = xmlTextReaderConstNamespaceUri(my_reader); | |
460 | const xmlChar *prefix = xmlTextReaderConstPrefix (my_reader); | |
461 | const xmlChar *lang = xmlTextReaderConstXmlLang (my_reader); | |
462 | const xmlChar *value = xmlTextReaderConstValue (my_reader); | |
463 | const xmlChar *encoding = xmlTextReaderConstEncoding (my_reader); | |
464 | const xmlChar *version = xmlTextReaderConstXmlVersion(my_reader); | |
465 | ||
466 | printf ("XML reader %d deep:\n" | |
467 | "\tbaseUri = '%s'\n" | |
468 | "\tprefix = '%s'\n" | |
469 | "\tlocalname = '%s'\n" | |
470 | "\tname = '%s%s'\n" | |
471 | "\tns-Uri = '%s'\n" | |
472 | "\txml lang = '%s'\n" | |
473 | "\tvalue = '%s'\n" | |
474 | "\tencoding = '%s'\n" | |
475 | "\txml ver = '%s'\n" | |
476 | , xmlTextReaderDepth(my_reader) | |
477 | , baseuri | |
478 | , prefix | |
479 | , localname | |
480 | , name, (xmlTextReaderIsEmptyElement(my_reader) ? "/" : "") | |
481 | , ns_uri | |
482 | , lang | |
483 | , value | |
484 | , encoding | |
485 | , version); | |
486 | } | |
487 | #endif | |
488 | ||
489 | ||
490 |