Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / parser / xml / Reader.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/parser/xml/Reader.h
10  *
11 */
12 #ifndef ZYPP_PARSER_XML_READER_H
13 #define ZYPP_PARSER_XML_READER_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/NonCopyable.h"
18 #include "zypp/base/InputStream.h"
19 #include "zypp/base/Function.h"
20
21 #include "zypp/parser/xml/Node.h"
22
23 ///////////////////////////////////////////////////////////////////
24 namespace zypp
25 { /////////////////////////////////////////////////////////////////
26   ///////////////////////////////////////////////////////////////////
27   namespace xml
28   { /////////////////////////////////////////////////////////////////
29
30     ///////////////////////////////////////////////////////////////////
31     //
32     //  CLASS NAME : Validate
33     //
34     /** xmlTextReader document validation.
35      * \todo Implement RelaxNG and W3C XSD
36      **/
37     struct Validate
38     {
39       static Validate none()
40       { return Validate(); }
41     };
42     ///////////////////////////////////////////////////////////////////
43
44     ///////////////////////////////////////////////////////////////////
45     //
46     //  CLASS NAME : Reader
47     //
48     /** xmlTextReader based interface to iterate xml streams.
49      *
50      * \code
51      * // Consume a node.
52      * bool consumeNode( xml::Reader & reader_r )
53      * {
54      *   DBG << *reader_r << endl;
55      *   return true;
56      * }
57      *
58      * // Consume all nodes (omitting attributes)
59      * void example()
60      * {
61      *   try
62      *     {
63      *       xml::Reader reader( "/Local/repodata/repomd.xml" );
64      *       reader.foreachNode( consumeNode );
65      *     }
66      *   catch ( const Exception & )
67      *     { ; } // parse error
68      * }
69      * \endcode
70      *
71      * \code
72      * // Consume a node.
73      * bool consumeNodeAndAttribute( xml::Reader & reader_r )
74      * {
75      *   consumeNode( reader_r );
76      *   return reader_r.foreachNodeAttribute( consumeNode );
77      * }
78      *
79      * // Consume all nodes and their attributes.
80      * void example()
81      * {
82      *   Pathname repodata( "/Local/repodata/repomd.xml" );
83      *   try
84      *     {
85      *       xml::Reader reader( "/Local/repodata/repomd.xml" );
86      *       reader.foreachNode( consumeNodeAndAttribute );
87      *       // or:
88      *       // reader.foreachNodeOrAttribute( consumeNode )
89      *     }
90      *   catch ( const Exception & )
91      *     { ; } // parse error
92      * }
93      * \endcode
94      **/
95     class Reader : private zypp::base::NonCopyable
96     {
97     public:
98       /** Ctor. Setup xmlTextReader and advance to the 1st Node. */
99       Reader( const InputStream & stream_r,
100               const Validate & validate_r = Validate::none() );
101
102       /** Dtor. */
103       ~Reader();
104
105     public:
106
107       /**
108        *  If the current node is not empty, advances the reader to the next
109        *  node, and returns the value
110        *
111        * \note if the node has a xml subtree you will probably jump to that node
112        * and get a empty text value back. Use it only if you are sure the node
113        * has no XML subtree.
114        */
115       XmlString nodeText();
116
117       /** */
118       bool nextNode();
119
120       /** */
121       bool nextNodeAttribute();
122
123       /** */
124       bool nextNodeOrAttribute()
125       { return( nextNodeAttribute() || nextNode() ); }
126
127       /** */
128       bool atEnd() const
129       { return( _node.readState() == XML_TEXTREADER_MODE_CLOSED ); }
130
131       /** */
132       const Node & operator*() const
133       { return _node; }
134
135       /** */
136       const Node * operator->() const
137       { return &_node; }
138
139     public:
140       /** */
141       typedef function<bool( Reader & )> ProcessNode;
142
143       /** */
144       bool foreachNode( ProcessNode fnc_r )
145       {
146         if ( _node.isAttribute() )
147           nextNode();
148         for ( ; ! atEnd(); nextNode() )
149           {
150             if ( ! fnc_r( *this ) )
151               return false;
152           }
153         return true;
154       }
155
156       /** */
157       bool foreachNodeAttribute( ProcessNode fnc_r )
158       {
159         if ( _node.isAttribute() && ! fnc_r( *this ) )
160           return false;
161         while( nextNodeAttribute() )
162           {
163             if ( ! fnc_r( *this ) )
164               return false;
165           }
166         return true;
167       }
168
169       /** */
170       bool foreachNodeOrAttribute( ProcessNode fnc_r )
171       {
172         for ( ; ! atEnd(); nextNodeOrAttribute() )
173           {
174             if ( ! fnc_r( *this ) )
175               return false;
176           }
177         return true;
178       }
179
180     public:
181       /** */
182       bool seekToNode( int depth_r, const std::string & name_r );
183
184       /** */
185       bool seekToEndNode( int depth_r, const std::string & name_r );
186
187     private:
188       void close();
189
190     private:
191       InputStream      _stream;
192       xmlTextReaderPtr _reader;
193       Node             _node;
194     };
195     ///////////////////////////////////////////////////////////////////
196
197     /////////////////////////////////////////////////////////////////
198   } // namespace xml
199   ///////////////////////////////////////////////////////////////////
200   /////////////////////////////////////////////////////////////////
201 } // namespace zypp
202 ///////////////////////////////////////////////////////////////////
203 #endif // ZYPP_PARSER_XML_READER_H