BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balxml_reader.h
Go to the documentation of this file.
1/// @file balxml_reader.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balxml_reader.h -*-C++-*-
8#ifndef INCLUDED_BALXML_READER
9#define INCLUDED_BALXML_READER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balxml_reader balxml_reader
15/// @brief Provide common reader protocol for parsing XML documents.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balxml
19/// @{
20/// @addtogroup balxml_reader
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balxml_reader-purpose"> Purpose</a>
25/// * <a href="#balxml_reader-classes"> Classes </a>
26/// * <a href="#balxml_reader-description"> Description </a>
27/// * <a href="#balxml_reader-node-type"> Node Type </a>
28/// * <a href="#balxml_reader-qualified-and-local-names"> Qualified and local names: </a>
29/// * <a href="#balxml_reader-base-uri"> Base URI </a>
30/// * <a href="#balxml_reader-encoding"> Encoding </a>
31/// * <a href="#balxml_reader-thread-safety"> Thread Safety </a>
32/// * <a href="#balxml_reader-usage"> Usage </a>
33/// * <a href="#balxml_reader-example-1-the-protocol-usage"> Example 1: The protocol usage </a>
34/// * <a href="#balxml_reader-example-2-the-protocol-implementation"> Example 2: The protocol implementation </a>
35///
36/// # Purpose {#balxml_reader-purpose}
37/// Provide common reader protocol for parsing XML documents.
38///
39/// # Classes {#balxml_reader-classes}
40///
41/// - balxml::Reader: protocol for fast, forward-only access to XML data stream
42///
43/// @see balxml_validatingreader,
44/// balxml_elementattribute,
45/// balxml::ErrorInfo,
46/// balxml_prefixstack,
47/// balxml_namespaceregistry
48///
49/// # Description {#balxml_reader-description}
50/// This component supplies an abstract class, `balxml::Reader`
51/// that defines an interface for accessing a forward-only, read-only stream of
52/// XML data. The `balxml::Reader` interface is somewhat similar to Microsoft
53/// XmlReader interface, which provides a simpler and more flexible programming
54/// model than the quasi-standard SAX/SAX2 model and a (potentially) more
55/// memory-efficient programming model than DOM. Access to the data is done in
56/// a cursor-like fashion, going forward on the document stream and stopping at
57/// each node along the way. A "node" is an XML syntactic construct such as
58/// the start of an element, the end of an element, element text, etc.. (See
59/// the `balxml::Reader::NodeType` enumeration for a complete list.) Note that,
60/// unlike the Microsoft interace, an element attribute is *not* considered a
61/// node in this interface, but is rather considered an attribute of a
62/// start-element node. In the documentation below the "current node" refers
63/// to the node on which the reader is currently positioned. The client code
64/// advances through all of the nodes in the XML document by calling the
65/// `advanceToNextNode` function repeatedly and processing each node in the
66/// order it appears in the xml document.
67///
68/// `balxml::Reader` supplies accessors that query a node's attributes, such as
69/// the node's type, name, value, element attributes, etc.. Note that each call
70/// to `advanceToNextNode` invalidates strings and data structures returned when
71/// the `balxml::Reader` accessors were call for the prior node. E.g., the
72/// pointer returned from `nodeName` for one node will *not* be valid once the
73/// reader has advanced to the next node. The fact that this interface provides
74/// so little prior context gives the derived-class implementations the
75/// potential to be very efficient in their use of memory.
76///
77/// Any derived class must adhere to the class-level and function-level contract
78/// documented in this component. Note that an object of a derived class
79/// implementation must be reusable such that, after parsing one document, the
80/// reader can be closed and re-opened to parse another document.
81///
82/// ## Node Type {#balxml_reader-node-type}
83///
84///
85/// An enumeration value that identifies a node as a specific XML construct,
86/// e.g., ELEMENT, END_ELEMENT, TEXT, CDATA, etc. (See the
87/// `balxml::Reader::NodeType` enumeration for a complete list.)
88///
89/// ## Qualified and local names: {#balxml_reader-qualified-and-local-names}
90///
91///
92/// XML documents may contain some qualified names. These are names with a
93/// prefix (optional) and a local name, separated by a colon. (The colon is
94/// present only if the prefix is present.) The prefix is a (typically short)
95/// word that is associated with a namespace URI via a namespace declaration.
96/// The local name specifies an entity within the specified namespace or, if no
97/// prefix is given, within the default namespace. For each qualified name, the
98/// `balxml::Reader` interface provides access to the entire qualified name and
99/// separate access to the prefix, the local name, the namespace URI, and the
100/// namespace ID.
101///
102/// ## Base URI {#balxml_reader-base-uri}
103///
104///
105/// Networked XML documents may comprise chunks of data aggregated using various
106/// W3C standard inclusion mechanisms and can contain nodes that come from
107/// different places. DTD entities are an example of this. The base URI tells
108/// you where a node comes from (see http://www.w3.org/TR/xmlbase/). The base
109/// URI of an element is:
110///
111/// 1. The base URI specified by an xml:base attribute on the element, if one
112/// exists, otherwise
113/// 2. The base URI of the element's parent element within the document or
114/// external entity, if one exists, otherwise
115/// 3. The base URI of the document entity or external entity containing the
116/// element.
117///
118/// If there is no base URI for a node being returned (for example, it was
119/// parsed from an in-memory string), then `nodeBaseUri` return an empty string.
120///
121/// ## Encoding {#balxml_reader-encoding}
122///
123///
124/// A XML document or any external reference (such as expanding an entity in a
125/// DTD file or reading a schema file) will be encoded, for example, in "ASCII,"
126/// "UTF-8," or "UTF-16". The document can also contain self-describing
127/// information as to which encoding was used when the document was created.
128/// Note that the encoding returned from the `documentEncoding` method can
129/// differ from the encoding of the strings returned from the `balxml::Reader`
130/// accessors; all strings returned by these accessors are UTF-8 regardless of
131/// the encoding used in the original document.
132///
133/// If encoding information is not provided in the document, the
134/// `balxml::Reader::open` method allows clients to specify an encoding to use.
135/// The encoding passed to `balxml::Reader::open` will take effect only when
136/// there is no encoding information in the original document, i.e., the
137/// encoding information obtained from the original document trumps all. If
138/// there is no encoding provided within the document and the client has not
139/// provided one via the `balxml::Reader::open` method, then a derived-class
140/// implementation should set the encoding to UTF-8. (See the
141/// `balxml::Reader::open` method for more details.)
142///
143/// ## Thread Safety {#balxml_reader-thread-safety}
144///
145///
146/// This component does not provide any functions that present a thread safety
147/// issue, since the `balxml::Reader` class is abstract and cannot be
148/// instantiated. There is no guarantee that any specific derived class will
149/// provide a thread-safe implementation.
150///
151/// ## Usage {#balxml_reader-usage}
152///
153///
154/// This section illustrates intended use of this component.
155///
156/// ### Example 1: The protocol usage {#balxml_reader-example-1-the-protocol-usage}
157///
158///
159/// The following string describes xml for a very simple user directory.
160/// The top level element contains one xml namespace attribute, with one
161/// embedded entry describing a user.
162/// @code
163/// const char TEST_XML_STRING[] =
164/// "<?xml version='1.0' encoding='UTF-8'?>\n"
165/// "<directory-entry xmlns:dir='http://bloomberg.com/schemas/directory'>\n"
166/// " <name>John Smith</name>\n"
167/// " <phone dir:phonetype='cell'>212-318-2000</phone>\n"
168/// " <address/>\n"
169/// "</directory-entry>\n";
170/// @endcode
171/// Suppose we need to extract the name of the user and his cellphone number
172/// from this entry.
173/// In order to read the XML, we first need to construct a
174/// `balxml::NamespaceRegistry` object, a `balxml::PrefixStack` object, and a
175/// `TestReader` object, where `TestReader` is an implementation of
176/// `balxml::Reader`.
177/// @code
178/// balxml::NamespaceRegistry namespaces;
179/// balxml::PrefixStack prefixStack(&namespaces);
180/// TestReader testReader;
181/// balxml::Reader& reader = testReader;
182/// @endcode
183/// The reader uses a `balxml::PrefixStack` to manage namespace prefixes.
184/// Installing a stack for an open reader leads to undefined behavior. So, we
185/// want to ensure that our reader is not open before installation.
186/// @code
187/// assert(false == reader.isOpen());
188///
189/// reader.setPrefixStack(&prefixStack);
190///
191/// assert(&prefixStack == reader.prefixStack());
192/// @endcode
193/// Next, we call the `open` method to setup the reader for parsing using the
194/// data contained in the XML string.
195/// @code
196/// reader.open(TEST_XML_STRING, sizeof(TEST_XML_STRING) -1, 0, "UTF-8");
197/// @endcode
198/// Confirm that the `bdem::Reader` has opened properly.
199/// @code
200/// assert(true == reader.isOpen());
201/// @endcode
202/// Then, iterate through the nodes to find the elements that are interesting to
203/// us. First, we'll find the user's name:
204/// @code
205/// int rc = 0;
206/// bsl::string name;
207/// bsl::string number;
208///
209/// do {
210/// rc = reader.advanceToNextNode();
211/// assert(0 == rc);
212/// } while (bsl::strcmp(reader.nodeName(), "name"));
213///
214/// rc = reader.advanceToNextNode();
215///
216/// assert(0 == rc);
217/// assert(3 == reader.nodeDepth());
218/// assert(balxml::Reader::e_NODE_TYPE_TEXT == reader.nodeType());
219/// assert(true == reader.nodeHasValue());
220///
221/// name.assign(reader.nodeValue());
222/// @endcode
223/// Next, advance to the user's phone number:
224/// @code
225/// do {
226/// rc = reader.advanceToNextNode();
227/// assert(0 == rc);
228/// } while (bsl::strcmp(reader.nodeName(), "phone"));
229///
230/// assert(false == reader.isEmptyElement());
231/// assert(1 == reader.numAttributes());
232///
233/// balxml::ElementAttribute elemAttr;
234///
235/// rc = reader.lookupAttribute(&elemAttr, 0);
236/// assert(0 == rc);
237/// assert(false == elemAttr.isNull());
238///
239/// if (!bsl::strcmp(elemAttr.value(), "cell")) {
240/// rc = reader.advanceToNextNode();
241///
242/// assert(0 == rc);
243/// assert(balxml::Reader::e_NODE_TYPE_TEXT == reader.nodeType());
244/// assert(true == reader.nodeHasValue());
245///
246/// number.assign(reader.nodeValue());
247/// }
248/// @endcode
249/// Now, verify the extracted data:
250/// @code
251/// assert("John Smith" == name);
252/// assert("212-318-2000" == number);
253/// @endcode
254/// Finally, close the reader:
255/// @code
256/// reader.close();
257/// assert(false == reader.isOpen());
258/// @endcode
259///
260/// ### Example 2: The protocol implementation {#balxml_reader-example-2-the-protocol-implementation}
261///
262///
263/// We have to implement all pure virtual functions of the `balxml::Reader`
264/// protocol, but to make the example easier to read and shorter we will stub
265/// some methods. Moreover, we will provide fake implementations of the methods
266/// used in this example, so our implementation will not handle the given XML
267/// fragment, but iterate through some supposititious XML structure.
268///
269/// First, let's introduce an array of "helper" structs. This array will be
270/// filled in with data capable of describing the information contained in the
271/// user directory XML above:
272/// @code
273/// struct TestNode {
274/// // A struct that contains information capable of describing an XML
275/// // node.
276///
277/// // TYPES
278/// struct Attribute {
279/// // This struct represents the qualified name and value of an XML
280/// // attribute.
281///
282/// const char *d_qname; // qualified name of the attribute
283/// const char *d_value; // value of the attribute
284/// };
285///
286/// enum {
287/// k_NUM_ATTRIBUTES = 5
288/// };
289///
290/// // DATA
291/// balxml::Reader::NodeType d_type;
292/// // type of the node
293///
294/// const char *d_qname;
295/// // qualified name of the node
296///
297/// const char *d_nodeValue;
298/// // value of the XML node (if it's null, 'hasValue()' returns
299/// // 'false')
300///
301/// int d_depthChange;
302/// // adjustment for the depth level of 'TestReader', valid values are
303/// // -1, 0 or 1
304///
305/// bool d_isEmpty;
306/// // flag indicating whether the element is empty
307///
308/// Attribute d_attributes[k_NUM_ATTRIBUTES];
309/// // array of attributes
310/// };
311///
312///
313/// static const TestNode fakeDocument[] = {
314/// // 'fakeDocument' is an array of 'TestNode' objects, that will be used
315/// // by the 'TestReader' to traverse and describe the user directory XML
316/// // above.
317///
318/// { balxml::Reader::e_NODE_TYPE_NONE,
319/// 0 , 0 , 0,
320/// false, {} },
321///
322/// { balxml::Reader::e_NODE_TYPE_XML_DECLARATION,
323/// "xml" , "version='1.0' encoding='UTF-8'", +1,
324/// false, {} },
325///
326/// { balxml::Reader::e_NODE_TYPE_ELEMENT,
327/// "directory-entry" , 0 , 0,
328/// false, {"xmlns:dir" , "http://bloomberg.com/schemas/directory"} },
329///
330/// { balxml::Reader::e_NODE_TYPE_ELEMENT,
331/// "name" , 0 , +1,
332/// false, {} },
333///
334/// { balxml::Reader::e_NODE_TYPE_TEXT,
335/// 0 , "John Smith" , +1,
336/// false, {} },
337///
338/// { balxml::Reader::e_NODE_TYPE_END_ELEMENT,
339/// "name" , 0 , -1,
340/// false, {} },
341///
342/// { balxml::Reader::e_NODE_TYPE_ELEMENT,
343/// "phone" , 0 , 0,
344/// false, {"dir:phonetype", "cell"} },
345///
346/// { balxml::Reader::e_NODE_TYPE_TEXT,
347/// 0 , "212-318-2000" , +1,
348/// false, {} },
349///
350/// { balxml::Reader::e_NODE_TYPE_END_ELEMENT,
351/// "phone" , 0 , -1,
352/// false, {} },
353///
354/// { balxml::Reader::e_NODE_TYPE_ELEMENT,
355/// "address" , 0 , 0,
356/// true, {} },
357///
358/// { balxml::Reader::e_NODE_TYPE_END_ELEMENT,
359/// "directory-entry", 0 , -1,
360/// false, {} },
361///
362/// { balxml::Reader::e_NODE_TYPE_NONE,
363/// 0 , 0 , 0,
364/// false, {} },
365/// };
366/// @endcode
367/// Now, create a class that implements the `balxml::Reader` interface. Note
368/// that documentation for class methods is omitted to reduce the text of the
369/// usage example. If necessary, it can be seen in the `balxml::Reader` class
370/// declaration.
371/// @code
372/// // ================
373/// // class TestReader
374/// // ================
375///
376/// class TestReader : public balxml::Reader {
377/// private:
378/// // DATA
379/// balxml::ErrorInfo d_errorInfo; // current error information
380///
381/// balxml::PrefixStack *d_prefixes; // prefix stack (held, not owned)
382///
383/// XmlResolverFunctor d_resolver; // place holder, not actually used
384///
385/// bool d_isOpen; // flag indicating whether the
386/// // reader is open
387///
388/// bsl::string d_encoding; // document encoding
389///
390/// int d_nodeDepth; // level of the current node
391///
392/// const TestNode *d_currentNode; // node being handled (held, not
393/// // owned)
394///
395/// // PRIVATE CLASS METHODS
396/// void setEncoding(const char *encoding);
397/// void adjustPrefixStack();
398///
399/// public:
400/// // CREATORS
401/// TestReader();
402/// virtual ~TestReader();
403///
404/// // MANIPULATORS
405/// virtual void setResolver(XmlResolverFunctor resolver);
406///
407/// virtual void setPrefixStack(balxml::PrefixStack *prefixes);
408///
409/// virtual int open(const char *filename, const char *encoding = 0);
410/// virtual int open(const char *buffer,
411/// size_t size,
412/// const char *url = 0,
413/// const char *encoding = 0);
414/// virtual int open(bsl::streambuf *stream,
415/// const char *url = 0,
416/// const char *encoding = 0);
417///
418/// virtual void close();
419///
420/// virtual int advanceToNextNode();
421///
422/// virtual int lookupAttribute(balxml::ElementAttribute *attribute,
423/// int index) const;
424/// virtual int lookupAttribute(balxml::ElementAttribute *attribute,
425/// const char *qname) const;
426/// virtual int lookupAttribute(
427/// balxml::ElementAttribute *attribute,
428/// const char *localName,
429/// const char *namespaceUri) const;
430/// virtual int lookupAttribute(
431/// balxml::ElementAttribute *attribute,
432/// const char *localName,
433/// int namespaceId) const;
434///
435/// virtual void setOptions(unsigned int flags);
436///
437/// // ACCESSORS
438/// virtual const char *documentEncoding() const;
439/// virtual XmlResolverFunctor resolver() const;
440/// virtual bool isOpen() const;
441/// virtual const balxml::ErrorInfo& errorInfo() const;
442/// virtual int getLineNumber() const;
443/// virtual int getColumnNumber() const;
444/// virtual balxml::PrefixStack *prefixStack() const;
445/// virtual NodeType nodeType() const;
446/// virtual const char *nodeName() const;
447/// virtual const char *nodeLocalName() const;
448/// virtual const char *nodePrefix() const;
449/// virtual int nodeNamespaceId() const;
450/// virtual const char *nodeNamespaceUri() const;
451/// virtual const char *nodeBaseUri() const;
452/// virtual bool nodeHasValue() const;
453/// virtual const char *nodeValue() const;
454/// virtual int nodeDepth() const;
455/// virtual int numAttributes() const;
456/// virtual bool isEmptyElement() const;
457/// virtual unsigned int options() const;
458/// };
459///
460/// // ----------------
461/// // class TestReader
462/// // ----------------
463///
464/// // PRIVATE CLASS METHODS
465/// inline
466/// void TestReader::setEncoding(const char *encoding)
467/// {
468/// d_encoding =
469/// (0 == encoding || '\0' == encoding[0]) ? "UTF-8" : encoding;
470/// }
471///
472/// inline
473/// void TestReader::adjustPrefixStack()
474/// {
475/// // Each time this object reads a 'e_NODE_TYPE_ELEMENT' node, it must
476/// // push a namespace prefix onto the prefix stack to handle in-scope
477/// // namespace calculations that happen inside XML documents where inner
478/// // namespaces can override outer ones.
479///
480/// if (balxml::Reader::e_NODE_TYPE_ELEMENT == d_currentNode->d_type) {
481/// for (int ii = 0; ii < TestNode::k_NUM_ATTRIBUTES; ++ii) {
482/// const char *prefix = d_currentNode->d_attributes[ii].d_qname;
483///
484/// if (!prefix || bsl::strncmp("xmlns", prefix, 5)) {
485/// continue;
486/// }
487///
488/// if (':' == prefix[5]) {
489/// d_prefixes->pushPrefix(
490/// prefix + 6, d_currentNode->d_attributes[ii].d_value);
491/// }
492/// else {
493/// // default namespace
494/// d_prefixes->pushPrefix(
495/// "", d_currentNode->d_attributes[ii].d_value);
496/// }
497/// }
498/// }
499/// else if (balxml::Reader::e_NODE_TYPE_NONE == d_currentNode->d_type) {
500/// d_prefixes->reset();
501/// }
502/// }
503///
504/// // PUBLIC CREATORS
505/// TestReader::TestReader()
506/// : d_errorInfo()
507/// , d_prefixes(0)
508/// , d_resolver()
509/// , d_isOpen(false)
510/// , d_encoding()
511/// , d_nodeDepth(0)
512/// , d_currentNode(0)
513/// {
514/// }
515///
516/// TestReader::~TestReader()
517/// {
518/// }
519///
520/// // MANIPULATORS
521/// void TestReader::setResolver(XmlResolverFunctor resolver)
522/// {
523/// d_resolver = resolver;
524/// }
525///
526/// void TestReader::setPrefixStack(balxml::PrefixStack *prefixes)
527/// {
528/// assert(!d_isOpen);
529///
530/// d_prefixes = prefixes;
531/// }
532///
533/// int TestReader::open(const char * /* filename */,
534/// const char * /* encoding */)
535/// {
536/// return -1; // STUB
537/// }
538///
539/// int TestReader::open(const char * /* buffer */,
540/// size_t /* size */,
541/// const char * /* url */,
542/// const char *encoding)
543/// {
544/// if (d_isOpen) {
545/// return false; // RETURN
546/// }
547/// d_isOpen = true;
548/// d_nodeDepth = 0;
549/// @endcode
550/// Note that we do not use the supplied buffer, but direct the internal
551/// iterator to the fake structure:
552/// @code
553/// d_currentNode = fakeDocument;
554///
555/// setEncoding(encoding);
556/// return 0;
557/// }
558///
559/// int TestReader::open(bsl::streambuf * /* stream */,
560/// const char * /* url */,
561/// const char * /* encoding */)
562/// {
563/// return -1; // STUB
564/// }
565///
566/// void TestReader::close()
567/// {
568/// if (d_prefixes) {
569/// d_prefixes->reset();
570/// }
571///
572/// d_isOpen = false;
573/// d_encoding.clear();
574/// d_nodeDepth = 0;
575/// d_currentNode = 0;
576/// }
577///
578/// int TestReader::advanceToNextNode()
579/// {
580/// if (!d_currentNode) {
581/// return -1; // RETURN
582/// }
583///
584/// const TestNode *nextNode = d_currentNode + 1;
585///
586/// if (balxml::Reader::e_NODE_TYPE_NONE == nextNode->d_type) {
587/// // The document ends when the type of the next node is
588/// // 'e_NODE_TYPE_NONE'.
589/// d_prefixes->reset();
590/// return 1; // RETURN
591/// }
592///
593/// d_currentNode = nextNode;
594///
595/// if (d_prefixes && 1 == d_nodeDepth) {
596/// // A 'TestReader' only recognizes namespace URIs that have the
597/// // prefix "xmlns:" on the top-level element. A 'TestReader' adds
598/// // such URIs to its prefix stack. It treats namespace URI
599/// // declarations on any other elements like normal attributes, and
600/// // resets its prefix stack once the top level element closes.
601/// adjustPrefixStack();
602/// }
603///
604/// d_nodeDepth += d_currentNode->d_depthChange;
605///
606/// return 0;
607/// }
608///
609/// int TestReader::lookupAttribute(balxml::ElementAttribute *attribute,
610/// int index) const
611/// {
612/// if (!d_currentNode ||
613/// index < 0 ||
614/// index >= TestNode::k_NUM_ATTRIBUTES) {
615/// return 1; // RETURN
616/// }
617///
618/// const char *qname = d_currentNode->d_attributes[index].d_qname;
619/// if ('\0' == qname[0]) {
620/// return 1; // RETURN
621/// }
622///
623/// attribute->reset(
624/// d_prefixes, qname, d_currentNode->d_attributes[index].d_value);
625/// return 0;
626/// }
627///
628/// int TestReader::lookupAttribute(
629/// balxml::ElementAttribute * /* attribute */,
630/// const char * /* qname */) const
631/// {
632/// return -1; // STUB
633/// }
634///
635/// int TestReader::lookupAttribute(
636/// balxml::ElementAttribute * /* attribute */,
637/// const char * /* localName */,
638/// const char * /* namespaceUri */) const
639/// {
640/// return -1; // STUB
641/// }
642///
643/// int TestReader::lookupAttribute(
644/// balxml::ElementAttribute * /* attribute */,
645/// const char * /* localName */,
646/// int /* namespaceId */) const
647/// {
648/// return -1; // STUB
649/// }
650///
651/// void TestReader::setOptions(unsigned int /* flags */)
652/// {
653/// return; // STUB
654/// }
655///
656/// // ACCESSORS
657/// const char *TestReader::documentEncoding() const
658/// {
659/// return d_encoding.c_str();
660/// }
661///
662/// TestReader::XmlResolverFunctor TestReader::resolver() const
663/// {
664/// return d_resolver;
665/// }
666///
667/// bool TestReader::isOpen() const
668/// {
669/// return d_isOpen;
670/// }
671///
672/// const balxml::ErrorInfo& TestReader::errorInfo() const
673/// {
674/// return d_errorInfo;
675/// }
676///
677/// int TestReader::getLineNumber() const
678/// {
679/// return 0; // STUB
680/// }
681///
682/// int TestReader::getColumnNumber() const
683/// {
684/// return 0; // STUB
685/// }
686///
687/// balxml::PrefixStack *TestReader::prefixStack() const
688/// {
689/// return d_prefixes;
690/// }
691///
692/// TestReader::NodeType TestReader::nodeType() const
693/// {
694/// if (!d_currentNode || !d_isOpen) {
695/// return e_NODE_TYPE_NONE; // RETURN
696/// }
697///
698/// return d_currentNode->d_type;
699/// }
700///
701/// const char *TestReader::nodeName() const
702/// {
703/// if (!d_currentNode || !d_isOpen) {
704/// return 0; // RETURN
705/// }
706///
707/// return d_currentNode->d_qname;
708/// }
709///
710/// const char *TestReader::nodeLocalName() const
711/// {
712/// if (!d_currentNode || !d_isOpen) {
713/// return 0; // RETURN
714/// }
715///
716/// // This simple 'TestReader' does not understand XML that contains
717/// // qualified node names. This means the local name of a node is always
718/// // equal to its qualified name, so this function simply returns
719/// // 'd_qname'.
720/// return d_currentNode->d_qname;
721/// }
722///
723/// const char *TestReader::nodePrefix() const
724/// {
725/// return ""; // STUB
726/// }
727///
728/// int TestReader::nodeNamespaceId() const
729/// {
730/// return -1; // STUB
731/// }
732///
733/// const char *TestReader::nodeNamespaceUri() const
734/// {
735/// return ""; // STUB
736/// }
737///
738/// const char *TestReader::nodeBaseUri() const
739/// {
740/// return ""; // STUB
741/// }
742///
743/// bool TestReader::nodeHasValue() const
744/// {
745/// if (!d_currentNode || !d_isOpen) {
746/// return false; // RETURN
747/// }
748///
749/// if (0 == d_currentNode->d_nodeValue) {
750/// return false; // RETURN
751/// }
752///
753/// return ('\0' != d_currentNode->d_nodeValue[0]);
754/// }
755///
756/// const char *TestReader::nodeValue() const
757/// {
758/// if (!d_currentNode || !d_isOpen) {
759/// return 0; // RETURN
760/// }
761///
762/// return d_currentNode->d_nodeValue;
763/// }
764///
765/// int TestReader::nodeDepth() const
766/// {
767/// return d_nodeDepth;
768/// }
769///
770/// int TestReader::numAttributes() const
771/// {
772/// for (int index = 0; index < TestNode::k_NUM_ATTRIBUTES; ++index) {
773/// if (0 == d_currentNode->d_attributes[index].d_qname) {
774/// return index; // RETURN
775/// }
776/// }
777///
778/// return TestNode::k_NUM_ATTRIBUTES;
779/// }
780///
781/// bool TestReader::isEmptyElement() const
782/// {
783/// return d_currentNode->d_isEmpty;
784/// }
785///
786/// unsigned int TestReader::options() const
787/// {
788/// return 0;
789/// }
790/// @endcode
791/// Finally, our implementation of `balxml::Reader` is complete. We may use this
792/// implementation as the `TestReader` in the first example.
793/// @}
794/** @} */
795/** @} */
796
797/** @addtogroup bal
798 * @{
799 */
800/** @addtogroup balxml
801 * @{
802 */
803/** @addtogroup balxml_reader
804 * @{
805 */
806
807#include <balscm_version.h>
808
809#include <balxml_errorinfo.h>
810
811#include <bslma_managedptr.h>
812
813#include <bsl_cstddef.h> // for size_t
814#include <bsl_functional.h>
815#include <bsl_ostream.h>
816#include <bsl_streambuf.h>
817
818
819namespace balxml {
820
821class ElementAttribute;
822class PrefixStack;
823
824 // ============
825 // class Reader
826 // ============
827
828/// This abstract class defines an interface for fast, forward-only access
829/// to XML data. An object belonging to a derived-class implementation of
830/// this protocol is required to be re-usable, such that a new XML document
831/// can be parsed using the same reader object by calling `close` followed
832/// by another `open`.
833///
834/// See @ref balxml_reader
835class Reader {
836
837 public:
838 // PUBLIC TYPES
839 enum NodeType {
840 // Node types, returned by 'nodeType' method, which represent a XML
841 // syntactic construct within a document. Note: Not every
842 // implementation of 'Reader' will distinguish among all of the node
843 // types.
861#ifndef BDE_OMIT_INTERNAL_DEPRECATED
900#endif // BDE_OMIT_INTERNAL_DEPRECATED
901 };
902
904
905 /// Type for a user supplied functor that finds and opens an external
906 /// resource for the specified `location` and/or `namespaceUri` and
907 /// returns that resource as a managed pointer to a stream. The
908 /// `location` argument specifies the location of the external resource
909 /// and is typically a filename or a URI, depending on the context. The
910 /// `namespaceUri` argument always refers to the XML namespace of the
911 /// entity to be resolved. A conforming functor returns an empty
912 /// managed pointer if it cannot resolve the resource. For example, the
913 /// reader may use a resolver to open an external entity, even if the
914 /// reader does not do validation (see definition of `<!ENTITY>` in the
915 /// XML standard). Note that either argument can be NULL in situations
916 /// where its value is not needed or can be computed from the other
917 /// argument.
918 typedef bsl::function<StreamBufPtr(const char *location,
919 const char *namespaceUri)>
921
922 // CLASS METHODS
923
924 /// Return a string representation for the specified `nodeType` code or
925 /// "(* UNKNOWN NODE TYPE *)" if `nodeType` is not one of the values
926 /// enumerated in `NodeType`.
927 static const char *nodeTypeAsString(NodeType nodeType);
928
929 // PUBLIC CREATORS
930
931 /// Destroy this object. The implementation for this pure abstract base
932 /// class does nothing.
933 virtual ~Reader(void);
934
935 // NON-VIRTUAL ACCESSORS (implemented in this base class)
936
937 /// Print the information about the current node to the specified output
938 /// `os` stream.
939 void dumpNode(bsl::ostream& os) const;
940
941 /// Return `true` if the derived object encountered a fatal error. This
942 /// method is equivalent to a call to `errorInfo().isFatalError();`
943 bool isFatalError() const;
944
945 /// Return `true` if the derived object encountered a error. This
946 /// method is equivalent to a call to `errorInfo().isError();`
947 bool isError() const;
948
949 /// Return `true` if the derived object encountered a warning. This
950 /// method is equivalent to a call to `errorInfo().isWarning();`
951 bool isWarning() const;
952
953 // MANIPULATORS - SETUP METHODS
954
955 /// Set the prefix stack to the stack at the optionally specified
956 /// `prefixes` address or disable prefix stack support if `prefixes` is
957 /// null. This stack is used to push and pop namespace prefixes as the
958 /// parse progresses, so that, at any point, the stack will reflect the
959 /// set of active prefixes for the current node. It is legitimate to
960 /// pass a stack that already contains prefixes, these prefixes shall be
961 /// preserved when `close` is called, i.e., the prefix stack shall be
962 /// returned to the stack depth it had when `setPrefixStack` was called.
963 /// The behavior is undefined if this method is called after calling
964 /// `open` and before calling `close`.
965 virtual void setPrefixStack(PrefixStack *prefixes) = 0;
966
967 /// Set the external XML resource resolver to the specified `resolver`.
968 /// The XML resource resolver is used by the @ref balxml_reader to find and
969 /// open an external resources (See the `XmlResolverFunctor` typedef for
970 /// more details). The XML resource resolver remains valid; it is not
971 /// affected by a call to `close` and should be available until the
972 /// reader is destroyed. The behavior is undefined if this method is
973 /// called after calling `open` and before calling `close`.
975
976 // MANIPULATORS - OPEN/CLOSE AND NAVIGATION METHODS
977
978 /// Set up the reader for parsing using the data contained in the XML
979 /// file described by the specified `filename`, and set the encoding
980 /// value to the optionally specified `encoding` ("ASCII", "UTF-8",
981 /// etc). Returns 0 on success and non-zero otherwise. The encoding
982 /// passed to `Reader::open` will take effect only when there is no
983 /// encoding information in the original document, i.e., the encoding
984 /// information obtained from the XML file described by the `filename`
985 /// trumps all. If there is no encoding provided within the document
986 /// and `encoding` is null or a blank string is passed, then set the
987 /// encoding to the default "UTF-8". It is an error to `open` a reader
988 /// that is already open. Note that the reader will not be on a valid
989 /// node until `advanceToNextNode` is called.
990 virtual int open(const char *filename, const char *encoding = 0) = 0;
991
992 /// Set up the reader for parsing using the data contained in the
993 /// specified (XML) `buffer` of the specified `size`, set the base URL
994 /// to the optionally specified `url` and set the encoding value to the
995 /// optionally specified `encoding` ("ASCII", "UTF-8", etc). Return 0
996 /// on success and non-zero otherwise. If `url` is null or a blank
997 /// string is passed, then base URL will be empty. The encoding passed
998 /// to `Reader::open` will take effect only when there is no encoding
999 /// information in the original document, i.e., the encoding information
1000 /// obtained from the (XML) `buffer` trumps all. If there is no
1001 /// encoding provided within the document and `encoding` is null or a
1002 /// blank string is passed, then set the encoding to the default
1003 /// "UTF-8". It is an error to `open` a reader that is already open.
1004 /// Note that the reader will not be on a valid node until
1005 /// `advanceToNextNode` is called.
1006 virtual int open(const char *buffer,
1007 bsl::size_t size,
1008 const char *url = 0,
1009 const char *encoding = 0) = 0;
1010
1011 /// Set up the reader for parsing using the data contained in the
1012 /// specified (XML) `stream`, set the base URL to the optionally
1013 /// specified `url` and set the encoding value to the optionally
1014 /// specified `encoding` ("ASCII", "UTF-8", etc). Return 0 on success
1015 /// and non-zero otherwise. If `url` is null or a blank string is
1016 /// passed, then base URL will be empty. The encoding passed to
1017 /// `Reader::open` will take effect only when there is no encoding
1018 /// information in the original document, i.e., the encoding information
1019 /// obtained from the (XML) `stream` trumps all. If there is no
1020 /// encoding provided within the document and `encoding` is null or a
1021 /// blank string is passed, then set the encoding to the default
1022 /// "UTF-8". It is an error to `open` a reader that is already open.
1023 /// Note that the reader will not be on a valid node until
1024 /// `advanceToNextNode` is called.
1025 virtual int open(bsl::streambuf *stream,
1026 const char *url = 0,
1027 const char *encoding = 0) = 0;
1028
1029 /// Close the reader. Most, but not all state is reset. Specifically,
1030 /// the XML resource resolver and the prefix stack remain. The prefix
1031 /// stack shall be returned to the stack depth it had when
1032 /// `setPrefixStack` was called. Call the method `open` to reuse the
1033 /// reader. Note that `close` invalidates all strings and data
1034 /// structures obtained via `Reader` accessors. E.g., the pointer
1035 /// returned from `nodeName` for this node will not be valid once
1036 /// `close` is called.
1037 virtual void close() = 0;
1038
1039 /// Move to the next node in the data steam created by `open` thus
1040 /// allowing the node's properties to be queried via the `Reader`
1041 /// accessors. Return 0 on successful read, 1 if there are no more
1042 /// nodes to read, and a negative number otherwise. Note that each call
1043 /// to `advanceToNextNode` invalidates strings and data structures
1044 /// returned when `Reader` accessors where call for the "prior node".
1045 /// E.g., the pointer returned from `nodeName` for this node will not be
1046 /// valid once `advanceToNextNode` is called. Note that the reader will
1047 /// not be on a valid node until the first call to `advanceToNextNode`
1048 /// after the reader is opened. TBD: add comment about insignificant
1049 /// white space.
1050 virtual int advanceToNextNode() = 0;
1051
1052 /// Find the attribute at the specified `index` in the current node, and
1053 /// fill in the specified `attribute` structure. Return 0 on success, 1
1054 /// if no attribute is found at the `index`, and an a negative value
1055 /// otherwise. The strings that were filled into the `attribute`
1056 /// structure are invalid upon the next `advanceToNextNode` or `close`
1057 /// is called.
1058 virtual int lookupAttribute(ElementAttribute *attribute,
1059 int index) const = 0;
1060
1061 /// Find the attribute with the specified `qname` (qualified name) in
1062 /// the current node, and fill in the specified `attribute` structure.
1063 /// Return 0 on success, 1 if there is no attribute found with `qname`,
1064 /// and a negative value otherwise. The strings that were filled into
1065 /// the `attribute` structure are invalid upon the next
1066 /// `advanceToNextNode` or `close` is called.
1067 virtual int lookupAttribute(ElementAttribute *attribute,
1068 const char *qname) const = 0;
1069
1070 /// Find the attribute with the specified `localName` and specified
1071 /// `namespaceUri` in the current node, and fill in the specified
1072 /// `attribute` structure. Return 0 on success, 1 if there is no
1073 /// attribute found with `localName` and `namespaceUri`, and a negative
1074 /// value otherwise. If `namespaceUri` == 0 or a blank string is
1075 /// passed, then the document's default namespace will be used. The
1076 /// strings that were filled into the `attribute` structure are invalid
1077 /// upon the next `advanceToNextNode` or `close` is called.
1078 virtual int
1080 const char *localName,
1081 const char *namespaceUri) const = 0;
1082
1083 /// Find the attribute with the specified `localName` and specified
1084 /// `namespaceId` in the current node, and fill in the specified
1085 /// `attribute` structure. Return 0 on success, 1 if there is no
1086 /// attribute found with `localName` and `namespaceId`, and a negative
1087 /// value otherwise. If `namespaceId` == -1, then the document's
1088 /// default namespace will be used. The strings that were filled into
1089 /// the `attribute` structure are invalid upon the next
1090 /// `advanceToNextNode` or `close` is called.
1091 virtual int
1093 const char *localName,
1094 int namespaceId) const = 0;
1095
1096 /// Set the options to the flags in the specified `flags`. The options
1097 /// for the reader are persistent, i.e., the options are not reset by
1098 /// `close`. The behavior is undefined if this method is called after
1099 /// calling `open` and before calling `close`; except that derived
1100 /// classes are permitted to specify valid behavior for calling this
1101 /// function for specific arguments while the reader is open.
1102 virtual void setOptions(unsigned int flags) = 0;
1103
1104 // ACCESSORS
1105
1106 /// Return the document encoding or NULL on error. The returned pointer
1107 /// is owned by this object and must not be modified or deallocated by
1108 /// the caller. The returned pointer becomes invalid when `close` is
1109 /// called or the reader is destroyed.
1110 virtual const char *documentEncoding() const = 0;
1111
1112 /// Return the external XML resource resolver.
1113 virtual XmlResolverFunctor resolver() const = 0;
1114
1115 /// Return true if `open` was called successfully and `close` has not
1116 /// yet been called and false otherwise.
1117 virtual bool isOpen() const = 0;
1118
1119 /// Return a reference to the non-modifiable error information for this
1120 /// reader. The returned value becomes invalid when `close` is called
1121 /// or the reader is destroyed.
1122 virtual const ErrorInfo& errorInfo() const = 0;
1123
1124 /// Return the current line number within the input stream. The current
1125 /// line is the last line for which the reader has not yet seen a
1126 /// newline. Lines are counted starting at one from the time a stream
1127 /// is provided to `open`. Return 0 if not available. Note that a
1128 /// derived-class implementation is not required to count lines and may
1129 /// just return 0.
1130 virtual int getLineNumber() const = 0;
1131
1132 /// Return the current column number within the input stream. The
1133 /// current column number is the number of characters since the last
1134 /// newline was read by the reader plus one, i.e., the first column of
1135 /// each line is column number one. Return 0 if not available. Note
1136 /// that a derived-class implementation is not required to count
1137 /// columns and may just return 0.
1138 virtual int getColumnNumber() const = 0;
1139
1140 /// Return a pointer to the modifiable prefix stack that is used by this
1141 /// reader to manage namespace prefixes or 0 if namespace support is
1142 /// disabled. The behavior is undefined if the returned prefix stack is
1143 /// augmented in any way after calling `open` and before calling
1144 /// `close`.
1145 virtual PrefixStack *prefixStack() const = 0;
1146
1147 /// Return the node type of the current node if the reader `isOpen` and
1148 /// has not encounter an error and `Reader::NONE` otherwise.
1149 virtual NodeType nodeType() const = 0;
1150
1151 /// Return the qualified name of the current node if the current node
1152 /// has a name and NULL otherwise. The returned pointer is owned by
1153 /// this object and must not be modified or deallocated by the caller.
1154 /// The returned pointer becomes invalid upon the next
1155 /// `advanceToNextNode`, when `close` is called or the reader is
1156 /// destroyed.
1157 virtual const char *nodeName() const = 0;
1158
1159 /// Return the local name of the current node if the current node has a
1160 /// local name and NULL otherwise. The returned pointer is owned by
1161 /// this object and must not be modified or deallocated by the caller.
1162 /// The returned pointer becomes invalid upon the next
1163 /// `advanceToNextNode`, when `close` is called or the reader is
1164 /// destroyed.
1165 virtual const char *nodeLocalName() const = 0;
1166
1167 /// Return the prefix name of the current node if the correct node has a
1168 /// prefix name and NULL otherwise. The returned pointer is owned by
1169 /// this object and must not be modified or deallocated by the caller.
1170 /// The returned pointer becomes invalid upon the next
1171 /// `advanceToNextNode`, when `close` is called or the reader is
1172 /// destroyed.
1173 virtual const char *nodePrefix() const = 0;
1174
1175 /// Return the namespace ID of the current node if the current node has
1176 /// a namespace id and a negative number otherwise.
1177 virtual int nodeNamespaceId() const = 0;
1178
1179 /// Return the namespace URI name of the current node if the current
1180 /// node has a namespace URI and NULL otherwise. The returned pointer
1181 /// is owned by this object and must not be modified or deallocated by
1182 /// the caller. The returned pointer becomes invalid upon the next
1183 /// `advanceToNextNode`, when `close` is called or the reader is
1184 /// destroyed.
1185 virtual const char *nodeNamespaceUri() const = 0;
1186
1187 /// Return the base URI name of the current node if the current node has
1188 /// a base URI and NULL otherwise. The returned pointer is owned by
1189 /// this object and must not be modified or deallocated by the caller.
1190 /// The returned pointer becomes invalid upon the next
1191 /// `advanceToNextNode`, when `close` is called or the reader is
1192 /// destroyed.
1193 virtual const char *nodeBaseUri() const = 0;
1194
1195 /// Return true if the current node has a value and false otherwise.
1196 virtual bool nodeHasValue() const = 0;
1197
1198 /// Return the value of the current node if the current node has a value
1199 /// and NULL otherwise. The returned pointer is owned by this object
1200 /// and must not be modified or deallocated by the caller. The returned
1201 /// pointer becomes invalid upon the next `advanceToNextNode`, when
1202 /// `close` is called or the reader is destroyed.
1203 virtual const char *nodeValue() const = 0;
1204
1205 /// Return the nesting depth of the current node in the XML document.
1206 /// The root node has depth 0.
1207 virtual int nodeDepth() const = 0;
1208
1209 /// Return the number of attributes for the current node if that node
1210 /// has attributes and 0 otherwise.
1211 virtual int numAttributes() const = 0;
1212
1213 /// Return true if the current node is an element (i.e., node type is
1214 /// `BAEXML_NODE_TYPE_ELEMENT`) that ends with `/>`; and false
1215 /// otherwise. Note that `<a/>` will be considered empty but `<a></a>`
1216 /// will not.
1217 virtual bool isEmptyElement() const = 0;
1218
1219 /// Return the option flags.
1220 virtual unsigned int options() const = 0;
1221};
1222
1223// FREE OPERATORS
1224
1225/// Print the specified node type `value` to the specified `stream` in
1226/// human-readable form and return a modifiable reference to `stream`.
1227bsl::ostream& operator<<(bsl::ostream& stream, Reader::NodeType value);
1228
1229// ============================================================================
1230// INLINE DEFINITIONS
1231// ============================================================================
1232
1233 // ------------
1234 // class Reader
1235 // ------------
1236
1237inline
1239{
1240 return errorInfo().isWarning();
1241}
1242
1243inline
1245{
1246 return errorInfo().isError();
1247}
1248
1249inline
1251{
1252 return errorInfo().isFatalError();
1253}
1254
1255} // close package namespace
1256
1257// FREE OPERATORS
1258inline
1259bsl::ostream& balxml::operator<<(bsl::ostream& stream, Reader::NodeType value)
1260{
1261 return stream << Reader::nodeTypeAsString(value);
1262}
1263
1264
1265
1266#endif // INCLUDED_BALXML_READER
1267
1268// ----------------------------------------------------------------------------
1269// Copyright 2015 Bloomberg Finance L.P.
1270//
1271// Licensed under the Apache License, Version 2.0 (the "License");
1272// you may not use this file except in compliance with the License.
1273// You may obtain a copy of the License at
1274//
1275// http://www.apache.org/licenses/LICENSE-2.0
1276//
1277// Unless required by applicable law or agreed to in writing, software
1278// distributed under the License is distributed on an "AS IS" BASIS,
1279// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1280// See the License for the specific language governing permissions and
1281// limitations under the License.
1282// ----------------------------- END-OF-FILE ----------------------------------
1283
1284/** @} */
1285/** @} */
1286/** @} */
Definition balxml_elementattribute.h:289
Definition balxml_errorinfo.h:353
bool isWarning() const
Definition balxml_errorinfo.h:530
bool isError() const
Definition balxml_errorinfo.h:536
bool isFatalError() const
Definition balxml_errorinfo.h:542
Definition balxml_prefixstack.h:137
Definition balxml_reader.h:835
virtual bool isEmptyElement() const =0
virtual void close()=0
virtual ~Reader(void)
virtual const char * nodeName() const =0
void dumpNode(bsl::ostream &os) const
virtual void setPrefixStack(PrefixStack *prefixes)=0
virtual const char * nodeNamespaceUri() const =0
virtual int advanceToNextNode()=0
virtual int open(bsl::streambuf *stream, const char *url=0, const char *encoding=0)=0
bslma::ManagedPtr< bsl::streambuf > StreamBufPtr
Definition balxml_reader.h:903
virtual NodeType nodeType() const =0
virtual int open(const char *filename, const char *encoding=0)=0
virtual bool isOpen() const =0
bool isError() const
Definition balxml_reader.h:1244
virtual const char * nodeLocalName() const =0
virtual int lookupAttribute(ElementAttribute *attribute, const char *localName, int namespaceId) const =0
virtual void setOptions(unsigned int flags)=0
virtual int lookupAttribute(ElementAttribute *attribute, const char *localName, const char *namespaceUri) const =0
virtual int nodeDepth() const =0
virtual unsigned int options() const =0
Return the option flags.
virtual XmlResolverFunctor resolver() const =0
Return the external XML resource resolver.
virtual void setResolver(XmlResolverFunctor resolver)=0
bsl::function< StreamBufPtr(const char *location, const char *namespaceUri)> XmlResolverFunctor
Definition balxml_reader.h:920
virtual const char * nodeBaseUri() const =0
virtual const char * nodePrefix() const =0
bool isFatalError() const
Definition balxml_reader.h:1250
static const char * nodeTypeAsString(NodeType nodeType)
virtual const char * documentEncoding() const =0
virtual int lookupAttribute(ElementAttribute *attribute, const char *qname) const =0
virtual const char * nodeValue() const =0
virtual int lookupAttribute(ElementAttribute *attribute, int index) const =0
NodeType
Definition balxml_reader.h:839
@ e_NODE_TYPE_CDATA
Definition balxml_reader.h:847
@ BAEXML_NODE_TYPE_DOCUMENT_TYPE
Definition balxml_reader.h:872
@ e_NODE_TYPE_ENTITY
Definition balxml_reader.h:849
@ NODE_TYPE_END_ELEMENT
Definition balxml_reader.h:897
@ NODE_TYPE_XML_DECLARATION
Definition balxml_reader.h:899
@ NODE_TYPE_PROCESSING_INSTRUCTION
Definition balxml_reader.h:887
@ BAEXML_NODE_TYPE_TEXT
Definition balxml_reader.h:864
@ NODE_TYPE_ENTITY_REFERENCE
Definition balxml_reader.h:885
@ NODE_TYPE_NONE
Definition balxml_reader.h:881
@ BAEXML_NODE_TYPE_WHITESPACE
Definition balxml_reader.h:875
@ NODE_TYPE_WHITESPACE
Definition balxml_reader.h:894
@ BAEXML_NODE_TYPE_XML_DECLARATION
Definition balxml_reader.h:880
@ e_NODE_TYPE_DOCUMENT_TYPE
Definition balxml_reader.h:853
@ BAEXML_NODE_TYPE_NONE
Definition balxml_reader.h:862
@ NODE_TYPE_CDATA
Definition balxml_reader.h:884
@ e_NODE_TYPE_TEXT
Definition balxml_reader.h:846
@ NODE_TYPE_END_ENTITY
Definition balxml_reader.h:898
@ BAEXML_NODE_TYPE_CDATA
Definition balxml_reader.h:865
@ BAEXML_NODE_TYPE_SIGNIFICANT_WHITESPACE
Definition balxml_reader.h:876
@ BAEXML_NODE_TYPE_END_ENTITY
Definition balxml_reader.h:879
@ e_NODE_TYPE_DOCUMENT_FRAGMENT
Definition balxml_reader.h:854
@ NODE_TYPE_DOCUMENT_FRAGMENT
Definition balxml_reader.h:892
@ e_NODE_TYPE_ELEMENT
Definition balxml_reader.h:845
@ e_NODE_TYPE_XML_DECLARATION
Definition balxml_reader.h:860
@ BAEXML_NODE_TYPE_END_ELEMENT
Definition balxml_reader.h:878
@ BAEXML_NODE_TYPE_ENTITY
Definition balxml_reader.h:867
@ NODE_TYPE_NOTATION
Definition balxml_reader.h:893
@ e_NODE_TYPE_SIGNIFICANT_WHITESPACE
Definition balxml_reader.h:857
@ e_NODE_TYPE_WHITESPACE
Definition balxml_reader.h:856
@ e_NODE_TYPE_NOTATION
Definition balxml_reader.h:855
@ e_NODE_TYPE_PROCESSING_INSTRUCTION
Definition balxml_reader.h:850
@ BAEXML_NODE_TYPE_PROCESSING_INSTRUCTION
Definition balxml_reader.h:868
@ NODE_TYPE_DOCUMENT_TYPE
Definition balxml_reader.h:891
@ NODE_TYPE_COMMENT
Definition balxml_reader.h:889
@ NODE_TYPE_DOCUMENT
Definition balxml_reader.h:890
@ BAEXML_NODE_TYPE_DOCUMENT
Definition balxml_reader.h:871
@ e_NODE_TYPE_NONE
Definition balxml_reader.h:844
@ NODE_TYPE_ENTITY
Definition balxml_reader.h:886
@ NODE_TYPE_SIGNIFICANT_WHITESPACE
Definition balxml_reader.h:895
@ BAEXML_NODE_TYPE_COMMENT
Definition balxml_reader.h:870
@ e_NODE_TYPE_DOCUMENT
Definition balxml_reader.h:852
@ e_NODE_TYPE_END_ENTITY
Definition balxml_reader.h:859
@ BAEXML_NODE_TYPE_DOCUMENT_FRAGMENT
Definition balxml_reader.h:873
@ NODE_TYPE_ELEMENT
Definition balxml_reader.h:882
@ BAEXML_NODE_TYPE_ELEMENT
Definition balxml_reader.h:863
@ NODE_TYPE_TEXT
Definition balxml_reader.h:883
@ e_NODE_TYPE_ENTITY_REFERENCE
Definition balxml_reader.h:848
@ e_NODE_TYPE_END_ELEMENT
Definition balxml_reader.h:858
@ e_NODE_TYPE_COMMENT
Definition balxml_reader.h:851
@ BAEXML_NODE_TYPE_ENTITY_REFERENCE
Definition balxml_reader.h:866
@ BAEXML_NODE_TYPE_NOTATION
Definition balxml_reader.h:874
bool isWarning() const
Definition balxml_reader.h:1238
virtual const ErrorInfo & errorInfo() const =0
virtual int getLineNumber() const =0
virtual int getColumnNumber() const =0
virtual bool nodeHasValue() const =0
Return true if the current node has a value and false otherwise.
virtual int open(const char *buffer, bsl::size_t size, const char *url=0, const char *encoding=0)=0
virtual PrefixStack * prefixStack() const =0
virtual int nodeNamespaceId() const =0
virtual int numAttributes() const =0
Forward declaration.
Definition bslstl_function.h:934
Definition bslma_managedptr.h:1182
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balxml_base64parser.h:150
bsl::ostream & operator<<(bsl::ostream &stream, const ConfigSchema &schema)