Update licenseheader text in source files for qtxmlpatterns Qt module
[profile/ivi/qtxmlpatterns.git] / doc / src / xml-processing / xml-processing.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the documentation of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:FDL$
10 ** GNU Free Documentation License
11 ** Alternatively, this file may be used under the terms of the GNU Free
12 ** Documentation License version 1.3 as published by the Free Software
13 ** Foundation and appearing in the file included in the packaging of
14 ** this file.
15 **
16 ** Other Usage
17 ** Alternatively, this file may be used in accordance with the terms
18 ** and conditions contained in a signed written agreement between you
19 ** and Nokia.
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \group xml-tools
30     \title XML Classes
31
32     \brief Classes that support XML, via, for example DOM and SAX.
33
34     These classes are relevant to XML users.
35
36     \generatelist{related}
37 */
38
39 /*!
40     \page xml-processing.html
41     \title XML Processing
42     \ingroup technology-apis    
43
44     \brief An Overview of the XML processing facilities in Qt.
45
46     In addition to core XML support, classes for higher level querying
47     and manipulation of XML data are provided by the QtXmlPatterns
48     module. In the QtSvg module, the QSvgRenderer and QSvgGenerator
49     classes can read and write a subset of SVG, an XML-based file
50     format. Qt also provides helper functions that may be useful to
51     those working with XML and XHTML: see Qt::escape() and
52     Qt::convertFromPlainText().
53
54     \section1 Topics:
55
56     \list
57     \o \l {Classes for XML Processing}
58     \o \l {An Introduction to Namespaces}
59     \o \l {XML Streaming}
60     \o \l {The SAX Interface}
61     \o \l {Working with the DOM Tree}
62     \o \l {XQuery}{XQuery/XPath and XML Schema}
63         \list
64         \o \l{A Short Path to XQuery}
65         \endlist
66     \endlist
67     
68     \section1 Classes for XML Processing
69
70     These classes are relevant to XML users.
71
72     \annotatedlist xml-tools
73 */
74
75 /*!
76     \page xml-namespaces.html
77     \title An Introduction to Namespaces
78     \target namespaces
79
80     \contentspage XML Processing
81     \nextpage XML Streaming
82
83     Parts of the Qt XML module documentation assume that you are familiar
84     with XML namespaces. Here we present a brief introduction; skip to
85     \link #namespacesConventions Qt XML documentation conventions \endlink
86     if you already know this material.
87
88     Namespaces are a concept introduced into XML to allow a more modular
89     design. With their help data processing software can easily resolve
90     naming conflicts in XML documents.
91
92     Consider the following example:
93
94     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 6
95
96     Here we find three different uses of the name \e title. If you wish to
97     process this document you will encounter problems because each of the
98     \e titles should be displayed in a different manner -- even though
99     they have the same name.
100
101     The solution would be to have some means of identifying the first
102     occurrence of \e title as the title of a book, i.e. to use the \e
103     title element of a book namespace to distinguish it from, for example,
104     the chapter title, e.g.:
105     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 7
106
107     \e book in this case is a \e prefix denoting the namespace.
108
109     Before we can apply a namespace to element or attribute names we must
110     declare it.
111
112     Namespaces are URIs like \e http://www.example.com/fnord/book/. This
113     does not mean that data must be available at this address; the URI is
114     simply used to provide a unique name.
115
116     We declare namespaces in the same way as attributes; strictly speaking
117     they \e are attributes. To make for example \e
118     http://www.example.com/fnord/ the document's default XML namespace \e
119     xmlns we write
120
121     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 8
122
123     To distinguish the \e http://www.example.com/fnord/book/ namespace from
124     the default, we must supply it with a prefix:
125
126     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 9
127
128     A namespace that is declared like this can be applied to element and
129     attribute names by prepending the appropriate prefix and a ":"
130     delimiter. We have already seen this with the \e book:title element.
131
132     Element names without a prefix belong to the default namespace. This
133     rule does not apply to attributes: an attribute without a prefix does
134     not belong to any of the declared XML namespaces at all. Attributes
135     always belong to the "traditional" namespace of the element in which
136     they appear. A "traditional" namespace is not an XML namespace, it
137     simply means that all attribute names belonging to one element must be
138     different. Later we will see how to assign an XML namespace to an
139     attribute.
140
141     Due to the fact that attributes without prefixes are not in any XML
142     namespace there is no collision between the attribute \e title (that
143     belongs to the \e author element) and for example the \e title element
144     within a \e chapter.
145
146     Let's clarify this with an example:
147     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 10
148
149     Within the \e document element we have two namespaces declared. The
150     default namespace \e http://www.example.com/fnord/ applies to the \e
151     book element, the \e chapter element, the appropriate \e title element
152     and of course to \e document itself.
153
154     The \e book:author and \e book:title elements belong to the namespace
155     with the URI \e http://www.example.com/fnord/book/.
156
157     The two \e book:author attributes \e title and \e name have no XML
158     namespace assigned. They are only members of the "traditional"
159     namespace of the element \e book:author, meaning that for example two
160     \e title attributes in \e book:author are forbidden.
161
162     In the above example we circumvent the last rule by adding a \e title
163     attribute from the \e http://www.example.com/fnord/ namespace to \e
164     book:author: the \e fnord:title comes from the namespace with the
165     prefix \e fnord that is declared in the \e book:author element.
166
167     Clearly the \e fnord namespace has the same namespace URI as the
168     default namespace. So why didn't we simply use the default namespace
169     we'd already declared? The answer is quite complex:
170     \list
171     \o attributes without a prefix don't belong to any XML namespace at
172     all, not even to the default namespace;
173     \o additionally omitting the prefix would lead to a \e title-title clash;
174     \o writing it as \e xmlns:title would declare a new namespace with the
175     prefix \e title instead of applying the default \e xmlns namespace.
176     \endlist
177
178     With the Qt XML classes elements and attributes can be accessed in two
179     ways: either by refering to their qualified names consisting of the
180     namespace prefix and the "real" name (or \e local name) or by the
181     combination of local name and namespace URI.
182
183     More information on XML namespaces can be found at
184     \l http://www.w3.org/TR/REC-xml-names/.
185
186     \target namespacesConventions
187     \section1 Conventions Used in the Qt XML Documentation
188
189     The following terms are used to distinguish the parts of names within
190     the context of namespaces:
191     \list
192     \o  The \e {qualified name}
193         is the name as it appears in the document. (In the above example \e
194         book:title is a qualified name.)
195     \o  A \e {namespace prefix} in a qualified name
196         is the part to the left of the ":". (\e book is the namespace prefix in
197         \e book:title.)
198     \o  The \e {local part} of a name (also refered to as the \e {local
199         name}) appears to the right of the ":". (Thus \e title is the
200         local part of \e book:title.)
201     \o  The \e {namespace URI} ("Uniform Resource Identifier") is a unique
202         identifier for a namespace. It looks like a URL
203         (e.g. \e http://www.example.com/fnord/ ) but does not require
204         data to be accessible by the given protocol at the named address.
205     \endlist
206
207     Elements without a ":" (like \e chapter in the example) do not have a
208     namespace prefix. In this case the local part and the qualified name
209     are identical (i.e. \e chapter).
210
211     \sa {DOM Bookmarks Example}, {SAX Bookmarks Example}
212 */
213
214 /*!
215     \page xml-streaming.html
216     \title XML Streaming
217
218     \previouspage An Introduction to Namespaces
219     \contentspage XML Processing
220     \nextpage The SAX Interface
221
222     Since version 4.3, Qt provides two new classes for reading and
223     writing XML: QXmlStreamReader and QXmlStreamWriter.
224
225     The QXmlStreamReader and QXmlStreamWriter are two new classes provided
226     in Qt 4.3 and later. A stream reader reports an XML document as a stream
227     of tokens. This differs from SAX as SAX applications provide handlers to
228     receive XML events from the parser whereas the QXmlStreamReader drives the
229     loop, pulling tokens from the reader when they are needed.
230     This pulling approach makes it possible to build recursive descent parsers,
231     allowing XML parsing code to be split into different methods or classes.
232
233     QXmlStreamReader is a well-formed XML 1.0 parser that excludes external
234     parsed entities. Hence, data provided by the stream reader adheres to the
235     W3C's criteria for well-formed XML, as long as no error occurs. Otherwise,
236     functions such as \l{QXmlStreamReader::atEnd()}{atEnd()},
237     \l{QXmlStreamReader::error()}{error()} and \l{QXmlStreamReader::hasError()}
238     {hasError()} can be used to check and view the errors.
239
240     An example of QXmlStreamReader implementation would be the \c XbelReader in
241     \l{QXmlStream Bookmarks Example}, which is a subclass of QXmlStreamReader.
242     The constructor takes \a treeWidget as a parameter and the class has Xbel
243     specific functions:
244
245     \snippet examples/xml/streambookmarks/xbelreader.h 1
246
247     \dots
248     \snippet examples/xml/streambookmarks/xbelreader.h 2
249     \dots
250
251     The \c read() function accepts a QIODevice and sets it with
252     \l{QXmlStreamReader::setDevice()}{setDevice()}. The
253     \l{QXmlStreamReader::raiseError()}{raiseError()} function is used to
254     display a custom error message, inidicating that the file's version
255     is incorrect.
256
257     \snippet examples/xml/streambookmarks/xbelreader.cpp 1
258
259     The pendent to QXmlStreamReader is QXmlStreamWriter, which provides an XML
260     writer with a simple streaming API. QXmlStreamWriter operates on a
261     QIODevice and has specialised functions for all XML tokens or events you
262     want to write, such as \l{QXmlStreamWriter::writeDTD()}{writeDTD()},
263     \l{QXmlStreamWriter::writeCharacters()}{writeCharacters()},
264     \l{QXmlStreamWriter::writeComment()}{writeComment()} and so on.
265
266     To write XML document with QXmlStreamWriter, you start a document with the
267     \l{QXmlStreamWriter::writeStartDocument()}{writeStartDocument()} function
268     and end it with \l{QXmlStreamWriter::writeEndDocument()}
269     {writeEndDocument()}, which implicitly closes all remaining open tags.
270     Element tags are opened with \l{QXmlStreamWriter::writeStartDocument()}
271     {writeStartDocument()} and followed by 
272     \l{QXmlStreamWriter::writeAttribute()}{writeAttribute()} or
273     \l{QXmlStreamWriter::writeAttributes()}{writeAttributes()},
274     element content, and then \l{QXmlStreamWriter::writeEndDocument()}
275     {writeEndDocument()}. Also, \l{QXmlStreamWriter::writeEmptyElement()}
276     {writeEmptyElement()} can be used to write empty elements.
277
278     Element content comprises characters, entity references or nested elements.
279     Content can be written with \l{QXmlStreamWriter::writeCharacters()}
280     {writeCharacters()}, a function that also takes care of escaping all
281     forbidden characters and character sequences,
282     \l{QXmlStreamWriter::writeEntityReference()}{writeEntityReference()},
283     or subsequent calls to \l{QXmlStreamWriter::writeStartElement()}
284     {writeStartElement()}.
285
286     The \c XbelWriter class from \l{QXmlStream Bookmarks Example} is a subclass
287     of QXmlStreamWriter. Its \c writeFile() function illustrates the core
288     functions of QXmlStreamWriter mentioned above:
289
290     \snippet examples/xml/streambookmarks/xbelwriter.cpp 1
291 */
292
293 /*!
294     \page xml-sax.html
295     \title The SAX interface
296
297     \previouspage XML Streaming
298     \contentspage XML Processing
299     \nextpage Working with the DOM Tree
300
301     SAX is an event-based standard interface for XML parsers.
302     The Qt interface follows the design of the SAX2 Java implementation.
303     Its naming scheme was adapted to fit the Qt naming conventions.
304     Details on SAX2 can be found at \l{http://www.saxproject.org}.
305
306     Support for SAX2 filters and the reader factory are under
307     development. The Qt implementation does not include the SAX1
308     compatibility classes present in the Java interface.
309
310     \section1 Introduction to SAX2
311
312     The SAX2 interface is an event-driven mechanism to provide the user with
313     document information. An "event" in this context means something
314     reported by the parser, for example, it has encountered a start tag,
315     or an end tag, etc.
316
317     To make it less abstract consider the following example:
318     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 3
319
320     Whilst reading (a SAX2 parser is usually referred to as "reader") 
321     the above document three events would be triggered:
322     \list 1
323     \o A start tag occurs (\c{<quote>}).
324     \o Character data (i.e. text) is found, "A quotation.".
325     \o An end tag is parsed (\c{</quote>}).
326     \endlist
327
328     Each time such an event occurs the parser reports it; you can set up
329     event handlers to respond to these events.
330
331     Whilst this is a fast and simple approach to read XML documents,
332     manipulation is difficult because data is not stored, simply handled
333     and discarded serially. The \l{Working with the DOM Tree}{DOM interface}
334     reads in and stores the whole document in a tree structure;
335     this takes more memory, but makes it easier to manipulate the
336     document's structure.
337
338     The Qt XML module provides an abstract class, \l QXmlReader, that
339     defines the interface for potential SAX2 readers. Qt includes a reader
340     implementation, \l QXmlSimpleReader, that is easy to adapt through
341     subclassing.
342
343     The reader reports parsing events through special handler classes:
344     \table
345     \header \o Handler class \o Description
346     \row \o \l QXmlContentHandler
347          \o Reports events related to the content of a document (e.g. the start tag
348             or characters).
349     \row \o \l QXmlDTDHandler
350          \o Reports events related to the DTD (e.g. notation declarations).
351     \row \o \l QXmlErrorHandler
352          \o Reports errors or warnings that occurred during parsing.
353     \row \o \l QXmlEntityResolver
354          \o Reports external entities during parsing and allows users to resolve
355             external entities themselves instead of leaving it to the reader.
356     \row \o \l QXmlDeclHandler
357          \o Reports further DTD related events (e.g. attribute declarations).
358     \row \o \l QXmlLexicalHandler
359          \o Reports events related to the lexical structure of the
360             document (the beginning of the DTD, comments etc.).
361     \endtable
362
363     These classes are abstract classes describing the interface. The \l
364     QXmlDefaultHandler class provides a "do nothing" default
365     implementation for all of them. Therefore users only need to overload
366     the QXmlDefaultHandler functions they are interested in. 
367
368     To read input XML data a special class \l QXmlInputSource is used.
369
370     Apart from those already mentioned, the following SAX2 support classes 
371     provide additional useful functionality:
372     \table
373     \header \o Class \o Description
374     \row \o \l QXmlAttributes
375          \o Used to pass attributes in a start element event.
376     \row \o \l QXmlLocator
377          \o Used to obtain the actual parsing position of an event.
378     \row \o \l QXmlNamespaceSupport
379          \o Used to implement namespace support for a reader. Note that
380             namespaces do not change the parsing behavior. They are only
381             reported through the handler.
382     \endtable
383
384     The \l{SAX Bookmarks example} illustrates how to subclass
385     QXmlDefaultHandler to read an XML bookmark file (XBEL) and
386     how to generate XML by hand.
387
388     \section1 SAX2 Features
389
390     The behavior of an XML reader depends on its support for certain
391     optional features. For example, a reader may have the feature "report
392     attributes used for namespace declarations and prefixes along with
393     the local name of a tag". Like every other feature this has a unique
394     name represented by a URI: it is called
395     \e http://xml.org/sax/features/namespace-prefixes.
396
397     The Qt SAX2 implementation can report whether the reader has
398     particular functionality using the QXmlReader::hasFeature()
399     function. Available features can be tested with QXmlReader::feature(),
400     and switched on or off using QXmlReader::setFeature(). 
401
402     Consider the example 
403     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 4
404     A reader that does not support the \e
405     http://xml.org/sax/features/namespace-prefixes feature would report
406     the element name \e document but not its attributes \e xmlns:book and
407     \e xmlns with their values. A reader with the feature \e
408     http://xml.org/sax/features/namespace-prefixes reports the namespace
409     attributes if the \link QXmlReader::feature() feature\endlink is
410     switched on.
411
412     Other features include \e http://xml.org/sax/features/namespace
413     (namespace processing, implies \e
414     http://xml.org/sax/features/namespace-prefixes) and \e
415     http://xml.org/sax/features/validation (the ability to report
416     validation errors). 
417
418     Whilst SAX2 leaves it to the user to define and implement whatever
419     features are required, support for \e
420     http://xml.org/sax/features/namespace (and thus \e
421     http://xml.org/sax/features/namespace-prefixes) is mandantory.
422     The \l QXmlSimpleReader implementation of \l QXmlReader,
423     supports them, and can do namespace processing.
424
425     \l QXmlSimpleReader is not validating, so it
426     does not support \e http://xml.org/sax/features/validation.
427
428     \section1 Namespace Support via Features
429
430     As we have seen in the previous section, we can configure the
431     behavior of the reader when it comes to namespace
432     processing. This is done by setting and unsetting the 
433     \e http://xml.org/sax/features/namespaces and
434     \e http://xml.org/sax/features/namespace-prefixes features.
435
436     They influence the reporting behavior in the following way:
437     \list 1
438     \o Namespace prefixes and local parts of elements and attributes can
439     be reported.
440     \o The qualified names of elements and attributes are reported.
441     \o \l QXmlContentHandler::startPrefixMapping() and \l
442     QXmlContentHandler::endPrefixMapping() are called by the reader.
443     \o Attributes that declare namespaces (i.e. the attribute \e xmlns and
444     attributes starting with \e{xmlns:}) are reported.
445     \endlist
446
447     Consider the following element:
448     \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 5
449     With \e http://xml.org/sax/features/namespace-prefixes set to true 
450     the reader will report four attributes; but with the \e
451     namespace-prefixes feature set to false only three, with the \e
452     xmlns:fnord attribute defining a namespace being "invisible" to the
453     reader.
454
455     The \e http://xml.org/sax/features/namespaces feature is responsible
456     for reporting local names, namespace prefixes and URIs. With \e
457     http://xml.org/sax/features/namespaces set to true the parser will
458     report \e title as the local name of the \e fnord:title attribute, \e
459     fnord being the namespace prefix and \e http://example.com/fnord/ as
460     the namespace URI. When \e http://xml.org/sax/features/namespaces is
461     false none of them are reported.
462
463     In the current implementation the Qt XML classes follow the definition
464     that the prefix \e xmlns itself isn't associated with any namespace at all
465     (see \link http://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-using 
466     http://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-using \endlink).
467     Therefore even with \e http://xml.org/sax/features/namespaces and
468     \e http://xml.org/sax/features/namespace-prefixes both set to true
469     the reader won't return either a local name, a namespace prefix or
470     a namespace URI for \e xmlns:fnord.
471
472     This might be changed in the future following the W3C suggestion
473     \link http://www.w3.org/2000/xmlns/ http://www.w3.org/2000/xmlns/ \endlink
474     to associate \e xmlns with the namespace \e http://www.w3.org/2000/xmlns. 
475
476     As the SAX2 standard suggests, \l QXmlSimpleReader defaults to having
477     \e http://xml.org/sax/features/namespaces set to true and
478     \e http://xml.org/sax/features/namespace-prefixes set to false.
479     When changing this behavior using \l QXmlSimpleReader::setFeature() 
480     note that the combination of both features set to
481     false is illegal.
482
483     \section2 Summary
484
485     \l QXmlSimpleReader implements the following behavior:
486
487     \table
488     \header \o (namespaces, namespace-prefixes)
489             \o Namespace prefix and local part
490             \o Qualified names
491             \o Prefix mapping
492             \o xmlns attributes
493     \row \o (true, false) \o Yes \o Yes* \o Yes \o No
494     \row \o (true, true) \o Yes \o Yes \o Yes \o Yes
495     \row \o (false, true) \o No* \o Yes \o No* \o Yes
496     \row \o (false, false) \i41 Illegal
497     \endtable
498
499     The behavior of the entries marked with an asterisk (*) is not specified by SAX.
500
501     \section1 Properties
502
503     Properties are a more general concept. They have a unique name,
504     represented as an URI, but their value is \c void*. Thus nearly
505     anything can be used as a property value. This concept involves some
506     danger, though: there is no means of ensuring type-safety; the user
507     must take care that they pass the right type. Properties are
508     useful if a reader supports special handler classes.
509
510     The URIs used for features and properties often look like URLs, e.g.
511     \c http://xml.org/sax/features/namespace. This does not mean that the
512     data required is at this address. It is simply a way of defining
513     unique names.
514
515     Anyone can define and use new SAX2 properties for their readers.
516     Property support is not mandatory.
517
518     To set or query properties the following functions are provided: \l
519     QXmlReader::setProperty(), \l QXmlReader::property() and \l
520     QXmlReader::hasProperty().                     
521 */
522
523 /*!
524     \page xml-dom.tml
525     \title Working with the DOM Tree
526     \target dom
527
528     \previouspage The SAX Interface
529     \contentspage XML Processing
530     \nextpage {XQuery}{XQuery/XPath and XML Schema}
531
532     DOM Level 2 is a W3C Recommendation for XML interfaces that maps the
533     constituents of an XML document to a tree structure. The specification
534     of DOM Level 2 can be found at \l{http://www.w3.org/DOM/}.
535
536     \target domIntro
537     \section1 Introduction to DOM
538
539     DOM provides an interface to access and change the content and
540     structure of an XML file. It makes a hierarchical view of the document
541     (a tree view). Thus -- in contrast to the SAX2 interface -- an object
542     model of the document is resident in memory after parsing which makes
543     manipulation easy. 
544
545     All DOM nodes in the document tree are subclasses of \l QDomNode. The
546     document itself is represented as a \l QDomDocument object.
547
548     Here are the available node classes and their potential child classes:
549
550     \list
551     \o \l QDomDocument: Possible children are
552             \list
553             \o \l QDomElement (at most one)
554             \o \l QDomProcessingInstruction
555             \o \l QDomComment
556             \o \l QDomDocumentType
557             \endlist
558     \o \l QDomDocumentFragment: Possible children are
559             \list
560             \o \l QDomElement
561             \o \l QDomProcessingInstruction
562             \o \l QDomComment
563             \o \l QDomText
564             \o \l QDomCDATASection
565             \o \l QDomEntityReference
566             \endlist
567     \o \l QDomDocumentType: No children
568     \o \l QDomEntityReference: Possible children are
569             \list
570             \o \l QDomElement
571             \o \l QDomProcessingInstruction
572             \o \l QDomComment
573             \o \l QDomText
574             \o \l QDomCDATASection
575             \o \l QDomEntityReference
576             \endlist
577     \o \l QDomElement: Possible children are
578             \list
579             \o \l QDomElement
580             \o \l QDomText
581             \o \l QDomComment
582             \o \l QDomProcessingInstruction
583             \o \l QDomCDATASection
584             \o \l QDomEntityReference
585             \endlist
586     \o \l QDomAttr: Possible children are
587             \list
588             \o \l QDomText
589             \o \l QDomEntityReference
590             \endlist
591     \o \l QDomProcessingInstruction: No children
592     \o \l QDomComment: No children
593     \o \l QDomText: No children
594     \o \l QDomCDATASection: No children
595     \o \l QDomEntity: Possible children are
596             \list
597             \o \l QDomElement
598             \o \l QDomProcessingInstruction
599             \o \l QDomComment
600             \o \l QDomText
601             \o \l QDomCDATASection
602             \o \l QDomEntityReference
603             \endlist
604     \o \l QDomNotation: No children
605     \endlist
606
607     With \l QDomNodeList and \l QDomNamedNodeMap two collection classes 
608     are provided: \l QDomNodeList is a list of nodes,
609     and \l QDomNamedNodeMap is used to handle unordered sets of nodes
610     (often used for attributes).
611
612     The \l QDomImplementation class allows the user to query features of the
613     DOM implementation.
614
615     To get started please refer to the \l QDomDocument documentation.
616     You might also want to take a look at the \l{DOM Bookmarks example},
617     which illustrates how to read and write an XML bookmark file (XBEL)
618     using DOM.
619 */