diff options
author | Jerome Pasion <jerome.pasion@digia.com> | 2012-11-22 16:35:24 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-11-23 13:16:20 +0100 |
commit | 051aeb291646745559c47da160193bdcbd34ef2b (patch) | |
tree | 50040152b4dfe22238ef0446c9e57ff1b345bdd4 /examples | |
parent | b34af22fcc7e9321e5a7943763cd68a1d51a36d5 (diff) | |
download | qtxmlpatterns-051aeb291646745559c47da160193bdcbd34ef2b.tar.gz |
Doc: Modularized Qt XML Patterns documentation.
-moved snippets, images, documentation to src/xmlpatterns
-fixed \snippet tag
-ported module information from qtdoc repository
-enabled "make docs" for the module
-set up qdocconf file and .index file
-updated tests/auto/patternistexamples to point to the new
snippet locations
Change-Id: Ifd10733c277c6dbacac42898c8e7bacd00d23f27
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'examples')
-rw-r--r-- | examples/xmlpatterns/filetree/doc/src/filetree.qdoc | 407 | ||||
-rw-r--r-- | examples/xmlpatterns/recipes/doc/src/recipes.qdoc | 150 | ||||
-rw-r--r-- | examples/xmlpatterns/schema/doc/src/schema.qdoc | 129 | ||||
-rw-r--r-- | examples/xmlpatterns/trafficinfo/doc/src/trafficinfo.qdoc | 149 | ||||
-rw-r--r-- | examples/xmlpatterns/xquery/doc/src/globalVariables.qdoc | 201 |
5 files changed, 1036 insertions, 0 deletions
diff --git a/examples/xmlpatterns/filetree/doc/src/filetree.qdoc b/examples/xmlpatterns/filetree/doc/src/filetree.qdoc new file mode 100644 index 0000000..d9c2aea --- /dev/null +++ b/examples/xmlpatterns/filetree/doc/src/filetree.qdoc @@ -0,0 +1,407 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/filetree + \title File System Example + + This example shows how to use Qt XML Patterns for querying non-XML + data that is modeled to look like XML. + + \tableofcontents + + \section1 Introduction + + The example models your computer's file system to look like XML and + allows you to query the file system with XQuery. Suppose we want to + find all the \c{cpp} files in the subtree beginning at + \c{/filetree}: + + \image filetree_1-example.png + + \section2 The User Inteface + + The example is shown below. First, we use \c{File->Open Directory} + (not shown) to select the \c{/filetree} directory. Then we use the + combobox on the right to select the XQuery that searches for \c{cpp} + files (\c{listCPPFiles.xq}). Selecting an XQuery runs the query, + which in this case traverses the model looking for all the \c{cpp} + files. The XQuery text and the query results are shown on the right: + + \image filetree_2-example.png + + Don't be mislead by the XML representation of the \c{/filetree} + directory shown on the left. This is not the node model itself but + the XML obtained by traversing the node model and outputting it as + XML. Constructing and using the custom node model is explained in + the code walk-through. + + \section2 Running your own XQueries + + You can write your own XQuery files and run them in the example + program. The file \c{xmlpatterns/filetree/queries.qrc} is the \l{The + Qt Resource System} {resource file} for this example. It is used in + \c{main.cpp} (\c{Q_INIT_RESOURCE(queries);}). It lists the XQuery + files (\c{.xq}) that can be selected in the combobox. + + \quotefromfile xmlpatterns/filetree/queries.qrc + \printuntil + + To add your own queries to the example's combobox, store your + \c{.xq} files in the \c{examples/xmlpatterns/filetree/queries} + directory and add them to \c{queries.qrc} as shown above. + + \section1 Code Walk-Through + + The strategy is to create a custom node model that represents the + directory tree of the computer's file system. That tree structure is + non-XML data. The custom node model must have the same callback + interface as the XML node models that the Qt XML Patterns query engine + uses to execute queries. The query engine can then traverse the + custom node model as if it were traversing the node model built from + an XML document. + + The required callback interface is in QAbstractXmlNodeModel, so we + create a custom node model by subclassing QAbstractXmlNodeModel and + providing implementations for its pure virtual functions. For many + cases, the implementations of several of the virtual functions are + always the same, so Qt XML Patterns also provides QSimpleXmlNodeModel, + which subclasses QAbstractXmlNodeModel and provides implementations + for the callback functions that you can ignore. By subclassing + QSimpleXmlNodeModel instead of QAbstractXmlNodeModel, you can reduce + development time. + + \section2 The Custom Node Model Class: FileTree + + The custom node model for this example is class \c{FileTree}, which + is derived from QSimpleXmlNodeModel. \c{FileTree} implements all the + callback functions that don't have standard implementations in + QSimpleXmlNodeModel. When you implement your own custom node model, + you must provide implementations for these callback functions: + + \snippet xmlpatterns/filetree/filetree.h 0 + \snippet xmlpatterns/filetree/filetree.h 1 + + The \c{FileTree} class declares four data members: + + \snippet xmlpatterns/filetree/filetree.h 2 + + The QVector \c{m_fileInfos} will contain the node model. Each + QFileInfo in the vector will represent a file or a directory in the + file system. At this point it is instructive to note that although + the node model class for this example (\c{FileTree}) actually builds + and contains the custom node model, building the custom node model + isn't always required. The node model class for the \l{QObject XML + Model Example} {QObject node model example} does not build its node + model but instead uses an already existing QObject tree as its node + model and just implements the callback interface for that already + existing data structure. In this file system example, however, + although we have an already existing data structure, i.e. the file + system, that data structure is not in memory and is not in a form we + can use. So we must build an analog of the file system in memory + from instances of QFileInfo, and we use that analog as the custom + node model. + + The two sets of flags, \c{m_filterAllowAll} and \c{m_sortFlags}, + contain OR'ed flags from QDir::Filters and QDir::SortFlags + respectively. They are set by the \c{FileTree} constructor and used + in calls to QDir::entryInfoList() for getting the child list for a + directory node, i.e. a QFileInfoList containing the file and + directory nodes for all the immediate children of a directory. + + The QVector \c{m_names} is an auxiliary component of the node + model. It holds the XML element and attribute names (QXmlName) for + all the node types that will be found in the node model. \c{m_names} + is indexed by the enum \c{FileTree::Type}, which specifies the node + types: + + \target Node_Type + \snippet xmlpatterns/filetree/filetree.h 4 + + \c{Directory} and \c{File} will represent the XML element nodes for + directories and files respectively, and the other enum values will + represent the XML attribute nodes for a file's path, name, suffix, + its size in bytes, and its mime type. The \c{FileTree} constructor + initializes \c{m_names} with an appropriate QXmlName for each + element and attribute type: + + \snippet xmlpatterns/filetree/filetree.cpp 2 + + Note that the constructor does \e{not} pre-build the entire node + model. Instead, the node model is built \e{incrementally} as the + query engine evaluates a query. To see how the query engine causes + the node model to be built incrementally, see \l{Building And + Traversing The Node Model}. To see how the query engine accesses the + node model, see \l{Accessing the node model}. See also: \l{Node + Model Building Strategy}. + + \section3 Accessing The Node Model + + Since the node model is stored outside the query engine in the + \c{FileTree} class, the query engine knows nothing about it and can + only access it by calling functions in the callback interface. When + the query engine calls any callback function to access data in the + node model, it passes a QXmlNodeModelIndex to identify the node in + the node model that it wants to access. Hence all the virtual + functions in the callback interface use a QXmlNodeModelIndex to + uniquely identify a node in the model. + + We use the index of a QFileInfo in \c{m_fileInfos} to uniquely + identify a node in the node model. To get the QXmlNodeModelIndex for + a QFileInfo, the class uses the private function \c{toNodeIndex()}: + + \target main toNodeIndex + \snippet xmlpatterns/filetree/filetree.cpp 1 + + It searches the \c{m_fileInfos} vector for a QFileInfo that matches + \c{fileInfo}. If a match is found, its array index is passed to + QAbstractXmlNodeModel::createIndex() as the \c data value for the + QXmlNodeIndex. If no match is found, the unmatched QFileInfo is + appended to the vector, so this function is also doing the actual + incremental model building (see \l{Building And Traversing The Node + Model}). + + Note that \c{toNodeIndex()} gets a \l{Node_Type} {node type} as the + second parameter, which it just passes on to + \l{QAbstractXmlNodeModel::createIndex()} {createIndex()} as the + \c{additionalData} value. Logically, this second parameter + represents a second dimension in the node model, where the first + dimension represents the \e element nodes, and the second dimension + represents each element's attribute nodes. The meaning is that each + QFileInfo in the \c{m_fileInfos} vector can represent an \e{element} + node \e{and} one or more \e{attribute} nodes. In particular, the + QFileInfo for a file will contain the values for the attribute nodes + path, name, suffix, size, and mime type (see + \c{FileTree::attributes()}). Since the attributes are contained in + the QFileInfo of the file element, there aren't actually any + attribute nodes in the node model. Hence, we can use a QVector for + \c{m_fileInfos}. + + A convenience overloading of \l{toNodeIndex of convenience} + {toNodeIndex()} is also called in several places, wherever it is + known that the QXmlNodeModelIndex being requested is for a directory + or a file and not for an attribute. The convenience function takes + only the QFileInfo parameter and calls the other \l{main toNodeIndex} + {toNodeIndex()}, after obtaining either the Directory or File node + type directly from the QFileInfo: + + \target toNodeIndex of convenience + \snippet xmlpatterns/filetree/filetree.cpp 0 + + Note that the auxiliary vector \c{m_names} is accessed using the + \l{Node_Type} {node type}, for example: + + \snippet xmlpatterns/filetree/filetree.cpp 3 + + Most of the virtual functions in the callback interface are as + simple as the ones described so far, but the callback function used + for traversing (and building) the node model is more complex. + + \section3 Building And Traversing The Node Model + + The node model in \c{FileTree} is not fully built before the query + engine begins evaluating the query. In fact, when the query engine + begins evaluating its first query, the only node in the node model + is the one representing the root directory for the selected part of + the file system. See \l{The UI Class: MainWindow} below for details + about how the UI triggers creation of the model. + + The query engine builds the node model incrementally each time it + calls the \l{next node on axis} {nextFromSimpleAxis()} callback + function, as it traverses the node model to evaluate a query. Thus + the query engine only builds the region of the node model that it + needs for evaluating the query. + + \l{next node on axis} {nextFromSimpleAxis()} takes an + \l{QAbstractXmlNodeModel::SimpleAxis} {axis identifier} and a + \l{QXmlNodeModelIndex} {node identifier} as parameters. The + \l{QXmlNodeModelIndex} {node identifier} represents the \e{context + node} (i.e. the query engine's current location in the model), and + the \l{QAbstractXmlNodeModel::SimpleAxis} {axis identifier} + represents the direction we want to move from the context node. The + function finds the appropriate next node and returns its + QXmlNodeModelIndex. + + \l{next node on axis} {nextFromSimpleAxis()} is where most of the + work of implementing a custom node model will be required. The + obvious way to do it is to use a switch statement with a case for + each \l{QAbstractXmlNodeModel::SimpleAxis} {axis}. + + \target next node on axis + \snippet xmlpatterns/filetree/filetree.cpp 4 + + The first thing this function does is call \l{to file info} + {toFileInfo()} to get the QFileInfo of the context node. The use of + QVector::at() here is guaranteed to succeed because the context node + must already be in the node model, and hence must have a QFileInfo + in \c{m_fileInfos}. + + \target to file info + \snippet xmlpatterns/filetree/filetree.cpp 6 + + The \l{QAbstractXmlNodeModel::Parent} {Parent} case looks up the + context node's parent by constructing a QFileInfo from the context + node's \l{QFileInfo::absoluteFilePath()} {path} and passing it to + \l{main toNodeIndex} {toNodeIndex()} to find the QFileInfo in + \c{m_fileInfos}. + + The \l{QAbstractXmlNodeModel::FirstChild} {FirstChild} case requires + that the context node must be a directory, because a file doesn't + have children. If the context node is not a directory, a default + constructed QXmlNodeModelIndex is returned. Otherwise, + QDir::entryInfoList() constructs a QFileInfoList of the context + node's children. The first QFileInfo in the list is passed to + \l{toNodeIndex of convenience} {toNodeIndex()} to get its + QXmlNodeModelIndex. Note that this will add the child to the node + model, if it isn't in the model yet. + + The \l{QAbstractXmlNodeModel::PreviousSibling} {PreviousSibling} and + \l{QAbstractXmlNodeModel::NextSibling} {NextSibling} cases call the + \l{nextSibling helper} {nextSibling() helper function}. It takes the + QXmlNodeModelIndex of the context node, the QFileInfo of the context + node, and an offest of +1 or -1. The context node is a child of some + parent, so the function gets the parent and then gets the child list + for the parent. The child list is searched to find the QFileInfo of + the context node. It must be there. Then the offset is applied, -1 + for the previous sibling and +1 for the next sibling. The resulting + index is passed to \l{toNodeIndex of convenience} {toNodeIndex()} to + get its QXmlNodeModelIndex. Note again that this will add the + sibling to the node model, if it isn't in the model yet. + + \target nextSibling helper + \snippet xmlpatterns/filetree/filetree.cpp 5 + + \section2 The UI Class: MainWindow + + The example's UI is a conventional Qt GUI application inheriting + QMainWindow and the Ui_MainWindow base class generated by + \l{Qt Designer Manual} {Qt Designer}. + + \snippet xmlpatterns/filetree/mainwindow.h 0 + + It contains the custom node model (\c{m_fileTree}) and an instance + of QXmlNodeModelIndex (\c{m_fileNode}) used for holding the node + index for the root of the file system subtree. \c{m_fileNode} will + be bound to a $variable in the XQuery to be evaluated. + + Two actions of interest are handled by slot functions: \l{Selecting + A Directory To Model} and \l{Selecting And Running An XQuery}. + + \section3 Selecting A Directory To Model + + The user selects \c{File->Open Directory} to choose a directory to + be loaded into the custom node model. Choosing a directory signals + the \c{on_actionOpenDirectory_triggered()} slot: + + \snippet xmlpatterns/filetree/mainwindow.cpp 1 + + The slot function simply calls the private function + \c{loadDirectory()} with the path of the chosen directory: + + \target the standard code pattern + \snippet xmlpatterns/filetree/mainwindow.cpp 4 + + \c{loadDirectory()} demonstrates a standard code pattern for using + Qt XML Patterns programatically. First it gets the node model index + for the root of the selected directory. Then it creates an instance + of QXmlQuery and calls QXmlQuery::bindVariable() to bind the node + index to the XQuery variable \c{$fileTree}. It then calls + QXmlQuery::setQuery() to load the XQuery text. + + \note QXmlQuery::bindVariable() must be called \e before calling + QXmlQuery::setQuery(), which loads and parses the XQuery text and + must have access to the variable binding as the text is parsed. + + The next lines create an output device for outputting the query + result, which is then used to create a QXmlFormatter to format the + query result as XML. QXmlQuery::evaluateTo() is called to run the + query, and the formatted XML output is displayed in the left panel + of the UI window. + + Finally, the private function \l{Selecting And Running An XQuery} + {evaluateResult()} is called to run the currently selected XQuery + over the custom node model. + + \note As described in \l{Building And Traversing The Node Model}, + the \c FileTree class wants to build the custom node model + incrementally as it evaluates the XQuery. But, because the + \c{loadDirectory()} function runs the \c{wholeTree.xq} XQuery, it + actually builds the entire node model anyway. See \l{Node Model + Building Strategy} for a discussion about building your custom node + model. + + \section3 Selecting And Running An XQuery + + The user chooses an XQuery from the menu in the combobox on the + right. Choosing an XQuery signals the + \c{on_queryBox_currentIndexChanged()} slot: + + \snippet xmlpatterns/filetree/mainwindow.cpp 2 + + The slot function opens and loads the query file and then calls the + private function \c{evaluateResult()} to run the query: + + \snippet xmlpatterns/filetree/mainwindow.cpp 3 + + \c{evaluateResult()} is a second example of the same code pattern + shown in \l{the standard code pattern} {loadDirectory()}. In this + case, it runs the XQuery currently selected in the combobox instead + of \c{qrc:/queries/wholeTree.xq}, and it outputs the query result to + the panel on the lower right of the UI window. + + \section2 Node Model Building Strategy + + We saw that the \l{The Custom Node Model Class: FileTree} {FileTree} + tries to build its custom node model incrementally, but we also saw + that the \l{the standard code pattern} {MainWindow::loadDirectory()} + function in the UI class immediately subverts the incremental build + by running the \c{wholeTree.xq} XQuery, which traverses the entire + selected directory, thereby causing the entire node model to be + built. + + If we want to preserve the incremental build capability of the + \c{FileTree} class, we can strip the running of \c{wholeTree.xq} out + of \l{the standard code pattern} {MainWindow::loadDirectory()}: + + \snippet xmlpatterns/filetree/mainwindow.cpp 5 + \snippet xmlpatterns/filetree/mainwindow.cpp 6 + + Note, however, that \c{FileTree} doesn't have the capability of + deleting all or part of the node model. The node model, once built, + is only deleted when the \c{FileTree} instance goes out of scope. + + In this example, each element node in the node model represents a + directory or a file in the computer's file system, and each node is + represented by an instance of QFileInfo. An instance of QFileInfo is + not costly to produce, but you might imagine a node model where + building new nodes is very costly. In such cases, the capability to + build the node model incrementally is important, because it allows + us to only build the region of the model we need for evaluating the + query. In other cases, it will be simpler to just build the entire + node model. + +*/ diff --git a/examples/xmlpatterns/recipes/doc/src/recipes.qdoc b/examples/xmlpatterns/recipes/doc/src/recipes.qdoc new file mode 100644 index 0000000..c42cfb9 --- /dev/null +++ b/examples/xmlpatterns/recipes/doc/src/recipes.qdoc @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/recipes + \title Recipes Example + + The Recipes example shows how to use Qt XML Patterns to query XML data + loaded from a file. + + \tableofcontents + + \section1 Introduction + + In this case, the XML data represents a cookbook, \c{cookbook.xml}, + which contains \c{<cookbook>} as its document element, which in turn + contains a sequence of \c{<recipe>} elements. This XML data is + searched using queries stored in XQuery files (\c{*.xq}). + + \section2 The User Interface + + The UI for this example was created using \l{Qt Designer Manual} {Qt + Designer}: + + \image recipes-example.png + + The UI consists of three \l{QGroupBox} {group boxes} arranged + vertically. The top one contains a \l{QTextEdit} {text viewer} that + displays the XML text from the cookbook file. The middle group box + contains a \l{QComboBox} {combo box} for choosing the \l{A Short + Path to XQuery} {XQuery} to run and a \l{QTextEdit} {text viewer} + for displaying the text of the selected XQuery. The \c{.xq} files in + the file list above are shown in the combo box menu. Choosing an + XQuery loads, parses, and runs the selected XQuery. The query result + is shown in the bottom group box's \l{QTextEdit} {text viewer}. + + \section2 Running your own XQueries + + You can write your own XQuery files and run them in the example + program. The file \c{xmlpatterns/recipes/recipes.qrc} is the \l{The + Qt Resource System} {resource file} for this example. It is used in + \c{main.cpp} (\c{Q_INIT_RESOURCE(recipes);}). It lists the XQuery + files (\c{.xq}) that can be selected in the combobox. + + \quotefromfile xmlpatterns/recipes/recipes.qrc + \printuntil + + To add your own queries to the example's combobox, store your + \c{.xq} files in the \c{examples/xmlpatterns/recipes/files} + directory and add them to \c{recipes.qrc} as shown above. + + \section1 Code Walk-Through + + The example's main() function creates the standard instance of + QApplication. Then it creates an instance of the UI class, shows it, + and starts the Qt event loop: + + \snippet xmlpatterns/recipes/main.cpp 0 + + \section2 The UI Class: QueryMainWindow + + The example's UI is a conventional Qt GUI application inheriting + QMainWindow and the class generated by \l{Qt Designer Manual} {Qt + Designer}: + + \snippet xmlpatterns/recipes/querymainwindow.h 0 + + The constructor finds the window's \l{QComboBox} {combo box} child + widget and connects its \l{QComboBox::currentIndexChanged()} + {currentIndexChanged()} signal to the window's \c{displayQuery()} + slot. It then calls \c{loadInputFile()} to load \c{cookbook.xml} and + display its contents in the top group box's \l{QTextEdit} {text + viewer} . Finally, it finds the XQuery files (\c{.xq}) and adds each + one to the \l{QComboBox} {combo box} menu. + + \snippet xmlpatterns/recipes/querymainwindow.cpp 0 + + The work is done in the \l{displayQuery() slot} {displayQuery()} + slot and the \l{evaluate() function} {evaluate()} function it + calls. \l{displayQuery() slot} {displayQuery()} loads and displays + the selected query file and passes the XQuery text to \l{evaluate() + function} {evaluate()}. + + \target displayQuery() slot + \snippet xmlpatterns/recipes/querymainwindow.cpp 1 + + \l{evaluate() function} {evaluate()} demonstrates the standard + Qt XML Patterns usage pattern. First, an instance of QXmlQuery is + created (\c{query}). The \c{query's} \l{QXmlQuery::bindVariable()} + {bindVariable()} function is then called to bind the \c cookbook.xml + file to the XQuery variable \c inputDocument. \e{After} the variable + is bound, \l{QXmlQuery::setQuery()} {setQuery()} is called to pass + the XQuery text to the \c query. + + \note \l{QXmlQuery::setQuery()} {setQuery()} must be called + \e{after} \l{QXmlQuery::bindVariable()} {bindVariable()}. + + Passing the XQuery to \l{QXmlQuery::setQuery()} {setQuery()} causes + Qt XML Patterns to parse the XQuery. \l{QXmlQuery::isValid()} is + called to ensure that the XQuery was correctly parsed. + + \target evaluate() function + \snippet xmlpatterns/recipes/querymainwindow.cpp 2 + + If the XQuery is valid, an instance of QXmlFormatter is created to + format the query result as XML into a QBuffer. To evaluate the + XQuery, an overload of \l{QXmlQuery::evaluateTo()} {evaluateTo()} is + called that takes a QAbstractXmlReceiver for its output + (QXmlFormatter inherits QAbstractXmlReceiver). Finally, the + formatted XML result is displayed in the UI's bottom text view. + + \note Each XQuery \c{.xq} file must declare the \c{$inputDocument} + variable to represent the \c cookbook.xml document: + + \code + (: All ingredients for Mushroom Soup. :) + declare variable $inputDocument external; + + doc($inputDocument)/cookbook/recipe[@xml:id = "MushroomSoup"]/ingredient/ + <p>{@name, @quantity}</p> + \endcode + + \note If you add add your own query.xq files, you must declare the + \c{$inputDocument} and use it as shown above. + +*/ diff --git a/examples/xmlpatterns/schema/doc/src/schema.qdoc b/examples/xmlpatterns/schema/doc/src/schema.qdoc new file mode 100644 index 0000000..0dc3a91 --- /dev/null +++ b/examples/xmlpatterns/schema/doc/src/schema.qdoc @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/schema + \title XML Schema Validation Example + + The XML Schema Validation example shows how to use Qt XML Patterns to + validate XML with a W3C XML Schema. + + \tableofcontents + + \section1 Introduction + + The example application shows different XML schema definitions and + for every definition two XML instance documents, one that is valid + according to the schema and one that is not. + The user can select the valid or invalid instance document, change + it and validate it again. + + \section2 The User Interface + + The UI for this example was created using \l{Qt Designer Manual} {Qt + Designer}: + + \image schema-example.png + + The UI consists of three parts, at the top the XML schema \l{QComboBox} {selection} + and the schema \l{QTextBrowser} {viewer}, below the XML instance \l{QComboBox} {selection} + and the instance \l{QTextEdit} {editor} and at the bottom the validation status \l{QLabel} {label} + next to the validation \l{QPushButton} {button}. + + \section2 Validating XML Instance Documents + + You can select one of the three predefined XML schemas and for each schema + an valid or invalid instance document. A click on the 'Validate' button will + validate the content of the XML instance editor against the schema from the + XML schema viewer. As you can modify the content of the instance editor, different + instances can be tested and validation error messages analysed. + + \section1 Code Walk-Through + + The example's main() function creates the standard instance of + QApplication. Then it creates an instance of the mainwindow class, shows it, + and starts the Qt event loop: + + \snippet xmlpatterns/schema/main.cpp 0 + + \section2 The UI Class: MainWindow + + The example's UI is a conventional Qt GUI application inheriting + QMainWindow and the class generated by \l{Qt Designer Manual} {Qt + Designer}: + + \snippet xmlpatterns/schema/mainwindow.h 0 + + The constructor fills the schema and instance \l{QComboBox} selections with the predefined + schemas and instances and connects their \l{QComboBox::currentIndexChanged()} {currentIndexChanged()} + signals to the window's \c{schemaSelected()} resp. \c{instanceSelected()} slot. + Furthermore the signal-slot connections for the validation \l{QPushButton} {button} + and the instance \l{QTextEdit} {editor} are set up. + + The call to \c{schemaSelected(0)} and \c{instanceSelected(0)} will trigger the validation + of the initial Contact Schema example. + + \snippet xmlpatterns/schema/mainwindow.cpp 0 + + In the \c{schemaSelected()} slot the content of the instance \l{QComboBox} {selection} + is adapted to the selected schema and the corresponding schema is loaded from the + \l{The Qt Resource System} {resource file} and displayed in the schema \l{QTextBrowser} {viewer}. + At the end of the method a revalidation is triggered. + + \snippet xmlpatterns/schema/mainwindow.cpp 1 + + In the \c{instanceSelected()} slot the selected instance is loaded from the + \l{The Qt Resource System} {resource file} and loaded into the instance \l{QTextEdit} {editor} + an the revalidation is triggered again. + + \snippet xmlpatterns/schema/mainwindow.cpp 2 + + The \c{validate()} slot does the actual work in this example. + At first it stores the content of the schema \l{QTextBrowser} {viewer} and the + \l{QTextEdit} {editor} into temporary \l{QByteArray} {variables}. + Then it instanciates a \c{MessageHandler} object which inherits from + \l{QAbstractMessageHandler} {QAbstractMessageHandler} and is a convenience + class to store error messages from the XmlPatterns system. + + \snippet xmlpatterns/schema/mainwindow.cpp 4 + + After the \l{QXmlSchema} {QXmlSchema} is instanciated and the message handler set + on it, the \l{QXmlSchema::load()} {load()} method is called with the schema data as argument. + If the schema is invalid or a parsing error has occured, \l{QXmlSchema::isValid()} {isValid()} + returns \c{false} and the error is flagged in \c{errorOccurred}. + If the loading was successful, a \l{QXmlSchemaValidator} {QXmlSchemaValidator} is + instanciated and the schema passed in the constructor. + A call to \l{QXmlSchemaValidator::validate()} {validate()} will validate the passed + XML instance data against the XML schema. The return value of that method signals + whether the validation was successful. + Depending on the success the status \l{QLabel} {label} is set to 'validation successful' + or the error message stored in the \c{MessageHandler} + + The rest of the code does only some fancy coloring and eyecandy. + + \snippet xmlpatterns/schema/mainwindow.cpp 3 +*/ diff --git a/examples/xmlpatterns/trafficinfo/doc/src/trafficinfo.qdoc b/examples/xmlpatterns/trafficinfo/doc/src/trafficinfo.qdoc new file mode 100644 index 0000000..7a8b7e8 --- /dev/null +++ b/examples/xmlpatterns/trafficinfo/doc/src/trafficinfo.qdoc @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/trafficinfo + \title TrafficInfo Example + + Shows how XQuery can be used extract information from WML documents provided by a WAP service. + + \section1 Overview + + The WAP service used in this example is \l{Trafikanten}{wap.trafikanten.no} + that is run by the Norwegian governmental agency for public transport in + Oslo. The service provides real time information about the departure of + busses, trams and undergrounds for every station in the city area. + + This example application displays the departure information for a specific + station and provides the feature to filter for a special bus or tram line. + + \image trafficinfo-example.png + + \section1 Retrieving the Data + + Without the knowledge of XQuery, one would use QNetworkAccessManager to + query the WML document from the WAP service and then using the QDom + classes or QXmlStreamReader classes to iterate over the document and + extract the needed information. + However this approach results in a lot of glue code and consumes valuable + developer time, so we are looking for something that can access XML + documents locally or over the network and extract data according to given + filter rules. That's the point where XQuery enters the stage! + + If we want to know when the underground number 6 in direction + \Aring\c{}sjordet is passing the underground station in Nydalen on November + 14th 2008 after 1pm, we use the following URL: + + \c{http://wap.trafikanten.no/F.asp?f=03012130&t=13&m=00&d=14.11.2008&start=1} + + The parameters have the following meanings: + \list + \li \e{f} The unique station ID of Nydalen. + \li \e{t} The hour in 0-23 format. + \li \e{m} The minute in 0-59 format. + \li \e{d} The date in dd.mm.yyyy format. + \li \e{start} Not interesting for our use but should be passed. + \endlist + + As a result we get the following document: + + \quotefile xmlpatterns/trafficinfo/time_example.wml + + So for every departure we have a \c <a> tag that contains the time as a + text element, and the following text element contains the line number + and direction. + + To encapsulate the XQuery code in the example application, we create a + custom \c TimeQuery class. This provides the \c queryInternal() function + that takes a station ID and date/time as input and returns the list of + times and directions: + + \snippet xmlpatterns/trafficinfo/timequery.cpp 1 + + The first lines of this function synthesize the XQuery strings that fetch + the document and extract the data. + For better readability, two separated queries are used here: the first one + fetches the times and the second fetches the line numbers and directions. + + The \c doc() XQuery method opens a local or remote XML document and returns + it, so the \c{/wml/card/p/small/} statement behind it selects all XML nodes + that can be reached by the path, \c wml \rarrow \c card \rarrow \c p \rarrow + \c small. + Now we are on the node that contains all the XML nodes we are interested in. + + In the first query we select all \c a nodes that have a \c href attribute + starting with the string "Rute" and return the text of these nodes. + + In the second query we select all text nodes that are children of the + \c small node which start with a number. + These two queries are passed to the QXmlQuery instance and are evaluated + to string lists. After some sanity checking, we have collected all the + information we need. + + In the section above we have seen that an unique station ID must be passed + as an argument to the URL for retrieving the time, so how to find out which + is the right station ID to use? The WAP service provides a page for that + as well, so the URL + + \c{http://wap.trafikanten.no/FromLink1.asp?fra=Nydalen} + + will return the following document: + + \snippet xmlpatterns/trafficinfo/station_example.wml 0 + + The names of the available stations are listed as separate text elements + and the station ID is part of the \c href attribute of the parent \c a + (anchor) element. In our example, the \c StationQuery class encapsulates + the action of querying the stations that match the given name pattern with + the following code: + + \snippet xmlpatterns/trafficinfo/stationquery.cpp 0 + + Just as in the \c TimeQuery implementation, the first step is to + synthesize the XQuery strings for selecting the station names and the + station IDs. As the station name that we pass in the URL will be input + from the user, we should protect the XQuery from code injection by using + the QXmlQuery::bindVariable() method to do proper quoting of the variable + content for us instead of concatenating the two strings manually. + + So, we define a XQuery \c $station variable that is bound to the user + input. This variable is concatenated inside the XQuery code with the + \c concat method. To extract the station IDs, we select all \c a elements + that have an \c title attribute with the content "Velg", and from these + elements we take the substring of the \c href attribute that starts at the + 18th character. + + The station name can be extracted a bit more easily by just taking the + text elements of the selected \a elements. + + After some sanity checks we have all the station IDs and the corresponding + names available. + + The rest of the code in this example is just for representing the time and + station information to the user, and uses techniques described in the + \l{Widget Examples}. +*/ diff --git a/examples/xmlpatterns/xquery/doc/src/globalVariables.qdoc b/examples/xmlpatterns/xquery/doc/src/globalVariables.qdoc new file mode 100644 index 0000000..08133f6 --- /dev/null +++ b/examples/xmlpatterns/xquery/doc/src/globalVariables.qdoc @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/xquery/globalVariables + \title C++ Source Code Analyzer Example + + This example uses XQuery and the \c xmlpatterns command line utility to + query C++ source code. + + \tableofcontents + + \section1 Introduction + + Suppose we want to analyze C++ source code to find coding standard + violations and instances of bad or inefficient patterns. We can do + it using the common searching and pattern matching utilities to + process the C++ files (e.g., \c{grep}, \c{sed}, and \c{awk}). Now + we can also use XQuery with the Qt XML Patterns module. + + An extension to the \c{g++} open source C++ compiler + (\l{http://public.kitware.com/GCC_XML/HTML/Index.html} {GCC-XML}) + generates an XML description of C++ source code declarations. This + XML description can then be processed by Qt XML Patterns using + XQueries to navigate the XML description of the C++ source and + produce a report. Consider the problem of finding mutable global + variables: + + \section2 Reporting Uses of Mutable Global Variables + + Suppose we want to introduce threading to a C++ application that + was originally written without threading. In a threaded program, + mutable global variables can cause bugs, because one thread might + change a global variable that other threads are reading, or two + threads might try to set the same global variable. So when + converting our program to use threading, one of the things we must + do is protect the global variables to prevent the bugs described + above. How can we use XQuery and + \l{http://public.kitware.com/GCC_XML/HTML/Index.html} {GCC-XML} to + find the variables that need protecting? + + \section3 A C++ application + + Consider the declarations in this hypothetical C++ application: + + \snippet xmlpatterns/xquery/globalVariables/globals.cpp 0 + + \section3 The XML description of the C++ application + + Submitting this C++ source to + \l{http://public.kitware.com/GCC_XML/HTML/Index.html} {GCC-XML} + produces this XML description: + + \quotefromfile xmlpatterns/xquery/globalVariables/globals.gccxml + \printuntil + + \section3 The XQuery for finding global variables + + We need an XQuery to find the global variables in the XML + description. Here is our XQuery source. We walk through it in + \l{XQuery Code Walk-Through}. + + \quotefromfile xmlpatterns/xquery/globalVariables/reportGlobals.xq + \printuntil + + \section3 Running the XQuery + + To run the XQuery using the \c xmlpatterns command line utility, + enter the following command: + + \code + xmlpatterns reportGlobals.xq -param fileToOpen=globals.gccxml -output globals.html + \endcode + + \section3 The XQuery output + + The \c xmlpatterns command loads and parses \c globals.gccxml, + runs the XQuery \c reportGlobals.xq, and generates this report: + + \div {class="details"} + Start report: 2008-12-16T13:43:49.65Z + \enddiv + + Global variables with complex types: + \list 1 + \li \span {class="variableName"} {mutableComplex1} in globals.cpp at line 14 + \li \span {class="variableName"} {mutableComplex2} in globals.cpp at line 15 + \li \span {class="variableName"} {constComplex1} in globals.cpp at line 16 + \li \span {class="variableName"} {constComplex2} in globals.cpp at line 17 + \endlist + + Mutable global variables with primitives types: + \list 1 + \li \span {class="variableName"} {mutablePrimitive1} in globals.cpp at line 1 + \li \span {class="variableName"} {mutablePrimitive2} in globals.cpp at line 2 + \endlist + + \div {class="details"} End report: 2008-12-16T13:43:49.65Z \enddiv + + \section1 XQuery Code Walk-Through + + The XQuery source is in + \c{examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq} + It begins with two variable declarations that begin the XQuery: + + \quotefromfile xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare variable + \printto (: + + The first variable, \c{$fileToOpen}, appears in the \c xmlpatterns + command shown earlier, as \c{-param fileToOpen=globals.gccxml}. + This binds the variable name to the file name. This variable is + then used in the declaration of the second variable, \c{$inDoc}, + as the parameter to the + \l{http://www.w3.org/TR/xpath-functions/#func-doc} {doc()} + function. The \c{doc()} function returns the document node of + \c{globals.gccxml}, which is assigned to \c{$inDoc} to be used + later in the XQuery as the root node of our searches for global + variables. + + Next skip to the end of the XQuery, where the \c{<html>} element + is constructed. The \c{<html>} will contain a \c{<head>} element + to specify a heading for the html page, followed by some style + instructions for displaying the text, and then the \c{<body>} + element. + + \quotefromfile xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto <html xmlns + \printuntil + + The \c{<body>} element contains a call to the \c{local:report()} + function, which is where the query does the "heavy lifting." Note + the two \c{return} clauses separated by the \e {comma operator} + about halfway down: + + \quotefromfile xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:report() + \printuntil }; + + The \c{return} clauses are like two separate queries. The comma + operator separating them means that both \c{return} clauses are + executed and both return their results, or, rather, both output + their results. The first \c{return} clause searches for global + variables with complex types, and the second searches for mutable + global variables with primitive types. + + Here is the html generated for the \c{<body>} element. Compare + it with the XQuery code above: + + \quotefromfile xmlpatterns/xquery/globalVariables/globals.html + \skipto <body> + \printuntil </body> + + The XQuery declares three more local functions that are called in + turn by the \c{local:report()} function. \c{isComplexType()} + returns true if the variable has a complex type. The variable can + be mutable or const. + + \quotefromfile xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:isComplexType + \printuntil }; + + \c{isPrimitive()} returns true if the variable has a primitive + type. The variable must be mutable. + + \quotefromfile xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:isPrimitive + \printuntil }; + + \c{location()} returns a text constructed from the variable's file + and line number attributes. + + \quotefromfile xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:location + \printuntil }; + + */ |