1 /*
2 Copyright (C) 2005 Matthias Braun <matze@braunis.de>
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 /** simple wrapper around libxml2 xmlreader interface */
19 
20 #ifndef __XMLREADER_HPP__
21 #define __XMLREADER_HPP__
22 
23 #include <libxml/xmlreader.h>
24 #include <stdexcept>
25 #include <sstream>
26 #include <iostream>
27 
28 class XmlReader
29 {
30 public:
31     XmlReader(const std::string& filename);
32     ~XmlReader();
33 
getDepth()34     int getDepth()
35     {
36         return xmlTextReaderDepth(reader);
37     }
38 
getNodeType()39     int getNodeType()
40     {
41         return xmlTextReaderNodeType(reader);
42     }
43 
hasValue()44     bool hasValue()
45     {
46         return xmlTextReaderHasValue(reader);
47     }
48 
isEmptyElement()49     bool isEmptyElement()
50     {
51         return xmlTextReaderIsEmptyElement(reader);
52     }
53 
getName()54     const xmlChar* getName()
55     {
56         return xmlTextReaderConstName(reader);
57     }
58 
getValue()59     const xmlChar* getValue()
60     {
61         return xmlTextReaderConstValue(reader);
62     }
63 
nextNode()64     void nextNode()
65     {
66         xmlTextReaderNext(reader);
67     }
68 
69     class AttributeIterator
70     {
71     public:
AttributeIterator(XmlReader & reader)72         AttributeIterator(XmlReader& reader)
73         {
74             this->reader = reader.reader;
75             first = true;
76             last = false;
77         }
78 
~AttributeIterator()79         ~AttributeIterator()
80         {
81             if(!last)
82                 xmlTextReaderMoveToElement(reader);
83         }
84 
next()85         bool next()
86         {
87             int res;
88             if(first) {
89                 res = xmlTextReaderMoveToFirstAttribute(reader);
90             } else {
91                 res = xmlTextReaderMoveToNextAttribute(reader);
92 
93             }
94 
95             if(res < 0)
96                 throw std::runtime_error("parse error.");
97             if(res == 0) {
98                 last = true;
99                 xmlTextReaderMoveToElement(reader);
100                 return false;
101             }
102             first = false;
103 
104             return true;
105         }
getName()106         const xmlChar* getName()
107         {
108             return xmlTextReaderConstName(reader);
109         }
getValue()110         const xmlChar* getValue()
111         {
112             return xmlTextReaderConstValue(reader);
113         }
114 
115     private:
116         bool first;
117         bool last;
118         xmlTextReaderPtr reader;
119     };
120 
read()121     bool read()
122     {
123         int ret = xmlTextReaderRead(reader);
124         if(ret < 0) {
125             std::stringstream msg;
126             /* This only works in libxml2.6.17 it seems... I have to upgrade
127              * sometime...
128              * msg << "Parse error at line " << xmlTextReaderGetParserLineNumber()...
129              */
130             msg << "Parser error";
131             throw std::runtime_error(msg.str());
132         }
133 
134         // Usefull for debug sometimes...
135 #if 0
136         for(int i = 0; i < getDepth(); ++i)
137             std::cout << " ";
138         std::cout << "T: " << getNodeType();
139         if(getName())
140             std::cout << " N:" << (const char*) getName();
141         if(getValue())
142             std::cout << " - " << (const char*) getValue();
143         std::cout << "\n";
144 #endif
145         return ret == 1;
146     }
147 
148 private:
149     xmlTextReaderPtr reader;
150 };
151 
152 #endif
153 
154