summaryrefslogtreecommitdiffstats
path: root/doc/xml-sax-features-walkthrough.doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/xml-sax-features-walkthrough.doc')
-rw-r--r--doc/xml-sax-features-walkthrough.doc391
1 files changed, 391 insertions, 0 deletions
diff --git a/doc/xml-sax-features-walkthrough.doc b/doc/xml-sax-features-walkthrough.doc
new file mode 100644
index 000000000..bc57a3c05
--- /dev/null
+++ b/doc/xml-sax-features-walkthrough.doc
@@ -0,0 +1,391 @@
+/****************************************************************************
+**
+** Documentation on the sax interface of the xml module
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing retquirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*! \page xml-sax-features-walkthrough.html
+
+\ingroup step-by-step-examples
+
+\title Walkthrough: Using SAX2 features with the Qt XML classes
+
+This document assumes that you are familiar with \link xml.html#namespaces
+namespaces \endlink in XML and the concept of a \link xml.html#sax2 SAX2
+parser \endlink.
+If features of SAX2 readers are new to you please read
+\link xml.html#sax2Features the feature section \endlink of the SAX2 document.
+
+As a novice to the Qt XML classes it is advisable to have a look at the
+\link xml-sax-walkthrough.html tiny SAX2 parser walkthrough \endlink before
+reading on.
+
+This walkthrough covers two topics: First of all it shows how to
+set SAX2 features and secondly how to integrate the Qt XML functionality
+into a Qt GUI application.
+
+The resulting application allows you to compare the output of the reader
+depending on how the two features
+\e http://xml.org/sax/features/namespace-prefixes
+and \e http://xml.org/sax/features/namespaces are set.
+To do this it shows tree views of the read XML file
+listing the qualified names of elements and attributes and the respective
+namespace URIs.
+
+<h3>Setting features</h3>
+
+\quotefile xml/tagreader-with-features/tagreader.cpp
+
+Let's begin with the main program of the application. First the boring
+part: we include all the classes we need:
+
+\skipto include
+\printline structureparser.h
+\printuntil qlabel.h
+
+\link #structureparser.h structureparser.h \endlink contains the API of
+the XML parser that we implement in \link #structureparser.cpp
+structureparser.cpp. \endlink
+
+\printline main
+\printuntil QApplication
+
+As usual we then create a Qt application object and hand command line arguments
+over to it.
+
+\printline xmlFile(
+
+If the user runs the program with one filename as
+an argument we process this file, otherwise we use the \e fnord.xml file from
+the example directory for demonstration purposes.
+
+\printline QXmlInputSource
+
+We use \e xmlFile as the XML Input Source...
+
+\printline QXmlSimpleReader
+
+... and instantiate a \e reader object. Later we will manipulate its features
+and thus influence how the XML data are read.
+
+\printline container
+
+Now let's think about presenting the output: As described in the
+\link xml.html#sax2Features Qt SAX2 documentation \endlink
+there are three valid combinations of \e
+http://xml.org/sax/features/namespace-prefixes
+and \e http://xml.org/sax/features/namespaces: TRUE/TRUE, TRUE/FALSE and
+FALSE/TRUE. To show the relevant output side by side of each other
+and mark them with three labels makes up for a grid layout consisting
+of three columns (and thus two lines).
+
+\printline nameSpace
+
+The most natural way of presenting XML elements is in a tree.
+Thus we use a listview. Its name \e nameSpace indicates that this
+one will be used to present the combination of \e
+http://xml.org/sax/features/namespaces being TRUE and
+\e http://xml.org/sax/features/namespace-prefixes
+being FALSE -- the default configuration of a \l QXmlSimpleReader.
+
+Being the first grid entry the \e nameSpace listview will
+appear in the upper left corner of the virtual grid.
+
+\printline handler
+
+Then we create a handler that deals with the XML data read by the reader.
+As the provided handler class \l QXmlDefaultHandler simply does nothing
+with the data from the reader,
+we can't use it right away. Instead we have to subclass our
+own \link #structureparser.cpp StructureParser \endlink from it.
+
+\printline setContentHandler
+
+The \e handler serves as content handler for the reader. Note that
+for simplicity reasons we don't register e.g. an error handler. Thus
+our program will not complain about for example missing closing tags
+in the parsed XML document.
+
+\printline parse
+
+Finally we parse the document with the reader's default feature settings.
+
+\printline namespacePrefix
+\printline table_namespace_prefix
+
+Now we prepare for the parsing of the same XML input source with
+different reader settings. The output will be presented in
+a second \l QListView, \e namespacePrefix. As it is the second
+member of the \e container grid it will appear in the middle of
+the upper grid row.
+
+\printline setListView
+
+Then we ask the \e handler to present the data in the \e namespacePrefix
+listview.
+
+\printline namespace-prefixes
+\printline TRUE
+
+Now we modify the behaviour of the \e reader and change
+\e http://xml.org/sax/features/namespace-prefixes from the default FALSE
+to TRUE. The \e http://xml.org/sax/features/namespaces feature has
+still its default setting TRUE.
+
+\printline reset
+
+We have to reset the input source to make the new parsing start from the
+beginning of the document again.
+
+\printline parse
+
+Finally we parse the XML file a second time with the changed reader
+settings (TRUE/TRUE).
+
+\printline prefix
+\printuntil parse
+
+Next we prepare and use the upper right listview to show the reader results
+with the feature setting \e http://xml.org/sax/features/namespaces
+FALSE and \e http://xml.org/sax/features/namespace-prefixes TRUE.
+
+\printline namespace label
+\printuntil namespace prefix label
+\printuntil prefix label
+\printuntil container
+
+The second row of the \e container grid is filled with three labels
+denoting the reader settings that belong to the above listview.
+
+\printline app.setMainWidget
+\printuntil }
+
+Same procedure as with every Qt GUI program: the grid serves as the
+main widget of our application and is shown. After that we enter
+the GUI's event loop.
+
+
+<h3><a name="structureparser.h">The handler API</a></h3>
+
+Let's have a brief look at the API of our handler class
+\e StructureParser:
+
+\quotefile xml/tagreader-with-features/structureparser.h
+\skipto include
+\printuntil QString
+
+\printline StructureParser
+\printuntil {
+
+We derive it from the \l QXmlDefaultHandler class that
+implements a handler that simply does nothing.
+
+\printuntil QListView
+
+This makes it easy for us to implement only the functionality
+we in fact need. In our case this is the constructor that
+takes a \l QListView as an argument,
+
+\printline startElement
+\printuntil QXmlAttributes
+
+the function to execute at the occurrence of element start tags
+(inherited from \l QXmlContentHandler), and
+
+\printline endElement
+
+the code to run when an end tag occurs.
+
+All we have to implement so far is content handling.
+
+\printline setListView
+
+In addition we have a function that selects a listview
+for the output.
+
+\printuntil QPtrStack
+
+Keep in mind that we write a SAX2 parser that doesn't
+have an object model to keep all elements and attributes
+in memory. To display the elements and attributes in a tree like
+structure we must however keep track of all elements
+that haven't been closed yet.
+
+To do this we use a LIFO stack
+of QListItems. An element will be added to the stack when
+its start tag appears and removed
+as soon as its end tag is parsed.
+
+\printline table
+\printline };
+
+Apart from this we define a member variable that contains
+the currently used listview.
+
+<h3><a name="structureparser.cpp">The handler itself</a></h3>
+
+Now that we defined the API we have to implement the
+relevant functions.
+
+\quotefile xml/tagreader-with-features/structureparser.cpp
+\skipto include
+\printuntil qlistview.h
+
+\printline StructureParser
+\printuntil {
+
+First we have the constructor that takes a listview pointer as
+its argument.
+
+\printline setListView
+\printuntil }
+
+All we have to do here is to prepare the argument \l QListView
+before usage. This we do with the \link #setListView()
+setListView() \endlink function.
+
+<a name="setListView()"></a>
+\printline setListView
+\printuntil table
+
+First we store the argument away.
+
+\printline setSorting
+
+We want the elements to be listed as they appear in the
+document -- and not for example sorted alphabetically. That's
+why we switch off sorting at all.
+
+\printline addColumn
+\printuntil }
+
+The listview now consists of two columns: one for the
+element's or attribute's qualified names and one for
+their namespace URIs. Columns are added from left to right
+and with the title as an argument.
+
+Now let's deal with XML content handling.
+
+\printline startElement
+\printuntil {
+
+When we come across the start tag of an element the handler does
+the real work. Although \e startElement is called with four
+arguments we keep track of only three: the namespace URI
+of the element, its qualified name and its attributes.
+If an element has no namespace assigned or if the feature
+settings of the reader don't provide the handler with
+namespace URIs at all \e namespaceURI contains an empty
+string.
+
+Note that we don't assign a variable to the second argument --
+we're simply not interested in the local name of the element.
+
+\printline element
+
+Whenever an element occurs we want to show it in the listview.
+Therefore we define a \l QListViewItem variable.
+
+\printline stack.isEmpty()
+\printline stack.top()
+
+As long as the element \e stack isn't empty the current element
+is a child of the topmost (last unclosed) element on the stack. Thus we
+create a new \l QListViewItem as a child of QPtrStack::stack.top() with
+the new element's qualified name in the first column and the according
+namespace URI (or nothing) in the second one.
+
+The QListViewItem is usally inserted as the first child. This means that we
+would get the elements in reverse order. So we first search for the last
+child of the QPtrStack::stack.top() element and insert it after this
+element.
+
+In a valid XML document this applies to all elements except
+the document root.
+
+\printuntil table
+\printline }
+
+The root element we have to handle separately because it is
+the first element to go onto the \l QListViewItem stack.
+Its listview item is therefore a direct child of the
+\e table listview itself.
+
+\printline stack.push
+
+Now we put the element's listview item on top of the stack.
+
+\printline setOpen
+
+By default a QListView presents all of its nodes closed.
+The user may then click on the \e + icon to see the child
+entries.
+
+We however want to see the entire element tree
+at once when we run the program.
+Therefore we open each listview item manually.
+
+\printline attributes.length
+
+What do we do if an element has attributes?
+
+\printuntil }
+\printline }
+
+For each of them we create a new listview item to present the attribute's
+qualified name and the relevant namespace URI (or nothing).
+Obviously \e attribute is a child of
+the current \e element.
+
+
+\printline TRUE
+\printline }
+
+To prevent the reader from throwing an error we have to
+return TRUE when we successfully dealt with an
+element's start tag.
+
+\printline endElement
+\printuntil stack.pop
+
+Whenever we come across an element's closing tag we
+have to remove its listview item from the stack as
+it can't have children any longer.
+
+\printuntil }
+
+And so we're done.
+
+*/