Imported Upstream version 2.91.2
[platform/upstream/libxml++.git] / docs / manual / html / ch02s02.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4 <title>SAX Parser</title>
5 <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
6 <link rel="home" href="index.html" title="libxml++ - An XML Parser for C++">
7 <link rel="up" href="chapter-parsers.html" title="Chapter 2. Parsers">
8 <link rel="prev" href="chapter-parsers.html" title="Chapter 2. Parsers">
9 <link rel="next" href="ch02s03.html" title="TextReader Parser">
10 </head>
11 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
12 <div class="navheader">
13 <table width="100%" summary="Navigation header">
14 <tr><th colspan="3" align="center">SAX Parser</th></tr>
15 <tr>
16 <td width="20%" align="left">
17 <a accesskey="p" href="chapter-parsers.html">Prev</a> </td>
18 <th width="60%" align="center">Chapter 2. Parsers</th>
19 <td width="20%" align="right"> <a accesskey="n" href="ch02s03.html">Next</a>
20 </td>
21 </tr>
22 </table>
23 <hr>
24 </div>
25 <div class="sect1">
26 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
27 <a name="idp89461168"></a>SAX Parser</h2></div></div></div>
28 <p>The SAX (Simple API for XML) parser presents each node of the XML document in sequence. So when you process one node, you must have already stored information about any relevant previous nodes, and you have no information at that time about subsequent nodes. The SAX parser uses less memory than the DOM parser and it is a suitable abstraction for documents that can be processed sequentially rather than as a whole.</p>
29 <p>By using the <code class="literal">parse_chunk()</code> method instead of <code class="literal">parse()</code>, you can even parse parts of the XML document before you have received the whole document.</p>
30 <p>As shown in the example, you should derive your own class from SaxParser and override some of the virtual methods. These "handler" methods will be called while the document is parsed.</p>
31 <div class="sect2">
32 <div class="titlepage"><div><div><h3 class="title">
33 <a name="idp89465008"></a>Example</h3></div></div></div>
34 <p>This example shows how the handler methods are called during parsing.</p>
35 <p><a class="ulink" href="http://git.gnome.org/browse/libxml++/tree/examples/sax_parser" target="_top">Source Code</a></p>
36 <p>File: myparser.h
37 </p>
38 <pre class="programlisting">
39 #ifndef __LIBXMLPP_EXAMPLES_MYPARSER_H
40 #define __LIBXMLPP_EXAMPLES_MYPARSER_H
41
42 #include &lt;libxml++/libxml++.h&gt;
43
44 class MySaxParser : public xmlpp::SaxParser
45 {
46 public:
47   MySaxParser();
48   ~MySaxParser() override;
49
50 protected:
51   //overrides:
52   void on_start_document() override;
53   void on_end_document() override;
54   void on_start_element(const Glib::ustring&amp; name,
55                                 const AttributeList&amp; properties) override;
56   void on_end_element(const Glib::ustring&amp; name) override;
57   void on_characters(const Glib::ustring&amp; characters) override;
58   void on_comment(const Glib::ustring&amp; text) override;
59   void on_warning(const Glib::ustring&amp; text) override;
60   void on_error(const Glib::ustring&amp; text) override;
61   void on_fatal_error(const Glib::ustring&amp; text) override;
62 };
63
64
65 #endif //__LIBXMLPP_EXAMPLES_MYPARSER_H
66 </pre>
67 <p>
68 </p>
69 <p>File: main.cc
70 </p>
71 <pre class="programlisting">
72 #ifdef HAVE_CONFIG_H
73 #include &lt;config.h&gt;
74 #endif
75
76 #include &lt;fstream&gt;
77 #include &lt;iostream&gt;
78 #include &lt;stdlib.h&gt;
79 #include &lt;cstring&gt; // std::memset()
80
81 #include "myparser.h"
82
83 int
84 main(int argc, char* argv[])
85 {
86   // Set the global C and C++ locale to the user-configured locale,
87   // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions.
88   std::locale::global(std::locale(""));
89
90   std::string filepath;
91   if(argc &gt; 1 )
92     filepath = argv[1]; //Allow the user to specify a different XML file to parse.
93   else
94     filepath = "example.xml";
95     
96   // Parse the entire document in one go:
97   auto return_code = EXIT_SUCCESS;
98   try
99   {
100     MySaxParser parser;
101     parser.set_substitute_entities(true);
102     parser.parse_file(filepath);
103   }
104   catch(const xmlpp::exception&amp; ex)
105   {
106     std::cerr &lt;&lt; "libxml++ exception: " &lt;&lt; ex.what() &lt;&lt; std::endl;
107     return_code = EXIT_FAILURE;
108   }
109
110   // Incremental parsing, sometimes useful for network connections:
111   try
112   {
113     std::cout &lt;&lt; std::endl &lt;&lt; "Incremental SAX Parser:" &lt;&lt; std::endl;
114     
115     std::ifstream is(filepath.c_str());
116     if (!is)
117       throw xmlpp::exception("Could not open file " + filepath);
118
119     char buffer[64];
120     const size_t buffer_size = sizeof(buffer) / sizeof(char);
121
122     //Parse the file:
123     MySaxParser parser;
124     parser.set_substitute_entities(true);
125     do
126     {
127       std::memset(buffer, 0, buffer_size);
128       is.read(buffer, buffer_size-1);
129       if(is.gcount())
130       {
131         // We use Glib::ustring::ustring(InputIterator begin, InputIterator end)
132         // instead of Glib::ustring::ustring( const char*, size_type ) because it
133         // expects the length of the string in characters, not in bytes.
134         Glib::ustring input(buffer, buffer+is.gcount());
135         parser.parse_chunk(input);
136       }
137     }
138     while(is);
139
140     parser.finish_chunk_parsing();
141   }
142   catch(const xmlpp::exception&amp; ex)
143   {
144     std::cerr &lt;&lt; "Incremental parsing, libxml++ exception: " &lt;&lt; ex.what() &lt;&lt; std::endl;
145     return_code = EXIT_FAILURE;
146   }
147
148   return return_code;
149 }
150
151 </pre>
152 <p>
153 </p>
154 <p>File: myparser.cc
155 </p>
156 <pre class="programlisting">
157 #include "myparser.h"
158 #include &lt;glibmm/convert.h&gt; //For Glib::ConvertError
159
160 #include &lt;iostream&gt;
161
162 MySaxParser::MySaxParser()
163   : xmlpp::SaxParser()
164 {
165 }
166
167 MySaxParser::~MySaxParser()
168 {
169 }
170
171 void MySaxParser::on_start_document()
172 {
173   std::cout &lt;&lt; "on_start_document()" &lt;&lt; std::endl;
174 }
175
176 void MySaxParser::on_end_document()
177 {
178   std::cout &lt;&lt; "on_end_document()" &lt;&lt; std::endl;
179 }
180
181 void MySaxParser::on_start_element(const Glib::ustring&amp; name,
182                                    const AttributeList&amp; attributes)
183 {
184   std::cout &lt;&lt; "node name=" &lt;&lt; name &lt;&lt; std::endl;
185
186   // Print attributes:
187   for(const auto&amp; attr_pair : attributes)
188   {
189     try
190     {
191       std::cout &lt;&lt; "  Attribute name=" &lt;&lt;  attr_pair.name &lt;&lt; std::endl;
192     }
193     catch(const Glib::ConvertError&amp; ex)
194     {
195       std::cerr &lt;&lt; "MySaxParser::on_start_element(): Exception caught while converting name for std::cout: " &lt;&lt; ex.what() &lt;&lt; std::endl;
196     }
197
198     try
199     {
200       std::cout &lt;&lt; "    , value= " &lt;&lt;  attr_pair.value &lt;&lt; std::endl;
201     }
202     catch(const Glib::ConvertError&amp; ex)
203     {
204       std::cerr &lt;&lt; "MySaxParser::on_start_element(): Exception caught while converting value for std::cout: " &lt;&lt; ex.what() &lt;&lt; std::endl;
205     }
206   }
207 }
208
209 void MySaxParser::on_end_element(const Glib::ustring&amp; /* name */)
210 {
211   std::cout &lt;&lt; "on_end_element()" &lt;&lt; std::endl;
212 }
213
214 void MySaxParser::on_characters(const Glib::ustring&amp; text)
215 {
216   try
217   {
218     std::cout &lt;&lt; "on_characters(): " &lt;&lt; text &lt;&lt; std::endl;
219   }
220   catch(const Glib::ConvertError&amp; ex)
221   {
222     std::cerr &lt;&lt; "MySaxParser::on_characters(): Exception caught while converting text for std::cout: " &lt;&lt; ex.what() &lt;&lt; std::endl;
223   }
224 }
225
226 void MySaxParser::on_comment(const Glib::ustring&amp; text)
227 {
228   try
229   {
230     std::cout &lt;&lt; "on_comment(): " &lt;&lt; text &lt;&lt; std::endl;
231   }
232   catch(const Glib::ConvertError&amp; ex)
233   {
234     std::cerr &lt;&lt; "MySaxParser::on_comment(): Exception caught while converting text for std::cout: " &lt;&lt; ex.what() &lt;&lt; std::endl;
235   }
236 }
237
238 void MySaxParser::on_warning(const Glib::ustring&amp; text)
239 {
240   try
241   {
242     std::cout &lt;&lt; "on_warning(): " &lt;&lt; text &lt;&lt; std::endl;
243   }
244   catch(const Glib::ConvertError&amp; ex)
245   {
246     std::cerr &lt;&lt; "MySaxParser::on_warning(): Exception caught while converting text for std::cout: " &lt;&lt; ex.what() &lt;&lt; std::endl;
247   }
248 }
249
250 void MySaxParser::on_error(const Glib::ustring&amp; text)
251 {
252   try
253   {
254     std::cout &lt;&lt; "on_error(): " &lt;&lt; text &lt;&lt; std::endl;
255   }
256   catch(const Glib::ConvertError&amp; ex)
257   {
258     std::cerr &lt;&lt; "MySaxParser::on_error(): Exception caught while converting text for std::cout: " &lt;&lt; ex.what() &lt;&lt; std::endl;
259   }
260 }
261
262 void MySaxParser::on_fatal_error(const Glib::ustring&amp; text)
263 {
264   try
265   {
266     std::cout &lt;&lt; "on_fatal_error(): " &lt;&lt; text &lt;&lt; std::endl;
267   }
268   catch(const Glib::ConvertError&amp; ex)
269   {
270     std::cerr &lt;&lt; "MySaxParser::on_characters(): Exception caught while converting value for std::cout: " &lt;&lt; ex.what() &lt;&lt; std::endl;
271   }
272 }
273
274 </pre>
275 <p>
276 </p>
277 </div>
278 </div>
279 <div class="navfooter">
280 <hr>
281 <table width="100%" summary="Navigation footer">
282 <tr>
283 <td width="40%" align="left">
284 <a accesskey="p" href="chapter-parsers.html">Prev</a> </td>
285 <td width="20%" align="center"><a accesskey="u" href="chapter-parsers.html">Up</a></td>
286 <td width="40%" align="right"> <a accesskey="n" href="ch02s03.html">Next</a>
287 </td>
288 </tr>
289 <tr>
290 <td width="40%" align="left" valign="top">Chapter 2. Parsers </td>
291 <td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
292 <td width="40%" align="right" valign="top"> TextReader Parser</td>
293 </tr>
294 </table>
295 </div>
296 </body>
297 </html>