diff options
Diffstat (limited to 'doc/src')
85 files changed, 5156 insertions, 0 deletions
diff --git a/doc/src/examples/filetree.qdoc b/doc/src/examples/filetree.qdoc new file mode 100644 index 0000000..718d0c8 --- /dev/null +++ b/doc/src/examples/filetree.qdoc @@ -0,0 +1,407 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/filetree + \title File System Example + + This example shows how to use QtXmlPatterns 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 examples/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 QtXmlPatterns 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 QtXmlPatterns 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 examples/xmlpatterns/filetree/filetree.h 0 + \snippet examples/xmlpatterns/filetree/filetree.h 1 + + The \c{FileTree} class declares four data members: + + \snippet examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/xmlpatterns/filetree/mainwindow.cpp 4 + + \c{loadDirectory()} demonstrates a standard code pattern for using + QtXmlPatterns 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 examples/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 examples/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 examples/xmlpatterns/filetree/mainwindow.cpp 5 + \snippet examples/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/doc/src/examples/globalVariables.qdoc b/doc/src/examples/globalVariables.qdoc new file mode 100644 index 0000000..224a3a7 --- /dev/null +++ b/doc/src/examples/globalVariables.qdoc @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $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 QtXmlPatterns 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 QtXmlPatterns 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 examples/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 examples/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 examples/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 + \o \span {class="variableName"} {mutableComplex1} in globals.cpp at line 14 + \o \span {class="variableName"} {mutableComplex2} in globals.cpp at line 15 + \o \span {class="variableName"} {constComplex1} in globals.cpp at line 16 + \o \span {class="variableName"} {constComplex2} in globals.cpp at line 17 + \endlist + + Mutable global variables with primitives types: + \list 1 + \o \span {class="variableName"} {mutablePrimitive1} in globals.cpp at line 1 + \o \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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:location + \printuntil }; + + */ diff --git a/doc/src/examples/recipes.qdoc b/doc/src/examples/recipes.qdoc new file mode 100644 index 0000000..f34fe3b --- /dev/null +++ b/doc/src/examples/recipes.qdoc @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/recipes + \title Recipes Example + + The recipes example shows how to use QtXmlPatterns 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 examples/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 examples/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 examples/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 examples/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 examples/xmlpatterns/recipes/querymainwindow.cpp 1 + + \l{evaluate() function} {evaluate()} demonstrates the standard + QtXmlPatterns 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 + QtXmlPatterns to parse the XQuery. \l{QXmlQuery::isValid()} is + called to ensure that the XQuery was correctly parsed. + + \target evaluate() function + \snippet examples/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/doc/src/examples/schema.qdoc b/doc/src/examples/schema.qdoc new file mode 100644 index 0000000..1cc4ed3 --- /dev/null +++ b/doc/src/examples/schema.qdoc @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/schema + \title XML Schema Validation Example + + This example shows how to use QtXmlPatterns 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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/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 examples/xmlpatterns/schema/mainwindow.cpp 3 +*/ diff --git a/doc/src/examples/trafficinfo.qdoc b/doc/src/examples/trafficinfo.qdoc new file mode 100644 index 0000000..c8ef3b0 --- /dev/null +++ b/doc/src/examples/trafficinfo.qdoc @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $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 + \o \e{f} The unique station ID of Nydalen. + \o \e{t} The hour in 0-23 format. + \o \e{m} The minute in 0-59 format. + \o \e{d} The date in dd.mm.yyyy format. + \o \e{start} Not interesting for our use but should be passed. + \endlist + + As a result we get the following document: + + \quotefile examples/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 examples/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 examples/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 examples/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/doc/src/images/filetree_1-example.png b/doc/src/images/filetree_1-example.png Binary files differnew file mode 100644 index 0000000..7e19174 --- /dev/null +++ b/doc/src/images/filetree_1-example.png diff --git a/doc/src/images/filetree_2-example.png b/doc/src/images/filetree_2-example.png Binary files differnew file mode 100644 index 0000000..cb794c5 --- /dev/null +++ b/doc/src/images/filetree_2-example.png diff --git a/doc/src/images/patternist-wordProcessor.png b/doc/src/images/patternist-wordProcessor.png Binary files differnew file mode 100644 index 0000000..0901330 --- /dev/null +++ b/doc/src/images/patternist-wordProcessor.png diff --git a/doc/src/images/recipes-example.png b/doc/src/images/recipes-example.png Binary files differnew file mode 100644 index 0000000..21ebc9b --- /dev/null +++ b/doc/src/images/recipes-example.png diff --git a/doc/src/images/schema-example.png b/doc/src/images/schema-example.png Binary files differnew file mode 100644 index 0000000..5e95bf5 --- /dev/null +++ b/doc/src/images/schema-example.png diff --git a/doc/src/images/trafficinfo-example.png b/doc/src/images/trafficinfo-example.png Binary files differnew file mode 100644 index 0000000..1717e40 --- /dev/null +++ b/doc/src/images/trafficinfo-example.png diff --git a/doc/src/snippets/code/doc_src_qtxml.qdoc b/doc/src/snippets/code/doc_src_qtxml.qdoc new file mode 100644 index 0000000..1e864ea --- /dev/null +++ b/doc/src/snippets/code/doc_src_qtxml.qdoc @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [3] +<quote>A quotation.</quote> +//! [3] + + +//! [4] +<document xmlns:book = 'http://example.com/fnord/book/' + xmlns = 'http://example.com/fnord/' > +//! [4] + + +//! [5] +<author xmlns:fnord = 'http://example.com/fnord/' + title="Ms" + fnord:title="Goddess" + name="Eris Kallisti"/> +//! [5] + + +//! [6] +<document> +<book> + <title>Practical XML</title> + <author title="Ms" name="Eris Kallisti"/> + <chapter> + <title>A Namespace Called fnord</title> + </chapter> +</book> +</document> +//! [6] + + +//! [7] +<book:title>Practical XML</book:title> +//! [7] + + +//! [8] +xmlns="http://example.com/fnord/" +//! [8] + + +//! [9] +xmlns:book="http://example.com/fnord/book/" +//! [9] + + +//! [10] +<document xmlns:book = 'http://example.com/fnord/book/' + xmlns = 'http://example.com/fnord/' > +<book> + <book:title>Practical XML</book:title> + <book:author xmlns:fnord = 'http://example.com/fnord/' + title="Ms" + fnord:title="Goddess" + name="Eris Kallisti"/> + <chapter> + <title>A Namespace Called fnord</title> + </chapter> +</book> +</document> +//! [10] diff --git a/doc/src/snippets/code/doc_src_qtxmlpatterns.qdoc b/doc/src/snippets/code/doc_src_qtxmlpatterns.qdoc new file mode 100644 index 0000000..22e2dde --- /dev/null +++ b/doc/src/snippets/code/doc_src_qtxmlpatterns.qdoc @@ -0,0 +1,306 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +void wrapInFunction() +{ + +//! [2] +xmlpatterns myQuery.xq +//! [2] + +//! [3] +declare namespace c = "http://cookbook/namespace"; +doc('cookbook.xml')//c:recipe/c:title +//! [3] + +//! [4] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')//recipe/title +//! [4] + +//! [5] +<title xmlns="http://cookbook/namespace">Quick and Easy Mushroom Soup</title> +<title xmlns="http://cookbook/namespace">Cheese on Toast</title> +<title xmlns="http://cookbook/namespace">Hard-Boiled Eggs</title> +//! [5] + +//! [6] +xmlpatterns file.xq +//! [6] + +//! [7] +doc('cookbook.xml')//@xml:* +//! [7] + +//! [8] +doc('cookbook.xml')//@*:name +//! [8] + +//! [9] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/@* +//! [9] + +//! [10] +declare default element namespace "http://cookbook/namespace"; +doc("cookbook.xml")/cookbook/recipe[title = "Hard-Boiled Eggs"] +//! [10] + +//! [11] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')//method[string-length(.) = 0] +//! [11] + +//! [12] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')//method[string-length() = 0] +//! [12] + +//! [13] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/recipe[2] +//! [13] + +//! [14] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/recipe[position() = 2] +//! [14] + +//! [15] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/recipe[position() > 1] +//! [15] + +//! [16] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/recipe[last()] +//! [16] + +//! [17] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/recipe[last() - 1] +//! [17] + +//! [18] +doc('cookbook.xml')//recipe +//! [18] + +//! [19] +doc('cookbook.xml')//recipe/title +//! [19] + +//! [20] +<recipe/> +//! [20] + +//! [21] + <html xmlns="http://www.w3.org/1999/xhtml/" + xml:id="{doc("other.html")/html/@xml:id}"/> +//! [21] + +//! [22] +doc('cookbook.xml')/descendant-or-self::element(recipe)/child::element(title) +//! [22] + +//! [23] +<cookbook> +//! [23] + +//! [24] +<cookbook xmlns="http://cookbook/namespace"> +//! [24] + +//! [25] +for $i in doc("cookbook.xml")//@xml:* +return <p>{$i}</p> +//! [25] + +//! [26] +for $i in doc("cookbook.xml")//@*:name +return <p>{$i}</p> +//! [26] + +//! [27] +declare default element namespace "http://cookbook/namespace"; +for $i in doc("cookbook.xml")/cookbook/@* +return <p>{$i}</p> +//! [27] + +//! [28] +<p xml:id="MushroomSoup"/> +<p xml:id="CheeseOnToast"/> +<p xml:id="HardBoiledEggs"/> +//! [28] + +//! [29] +<p name="Fresh mushrooms"/> +<p name="Garlic"/> +<p name="Olive oil"/> +<p name="Milk"/> +<p name="Water"/> +<p name="Cream"/> +<p name="Vegetable soup cube"/> +<p name="Ground black pepper"/> +<p name="Dried parsley"/> +<p name="Bread"/> +<p name="Cheese"/> +<p name="Eggs"/> +//! [29] + +//! [30] +<p xmlns="http://cookbook/namespace" count="3"/> +//! [30] + +//! [31] +<method xmlns="http://cookbook/namespace"/> +//! [31] + +//! [32] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')//recipe[string-length(method) = 0] +//! [32] + +//! [33] +<recipe xmlns="http://cookbook/namespace" xml:id="HardBoiledEggs"> + <title>Hard-Boiled Eggs</title> + <ingredient name="Eggs" quantity="3" unit="eggs"/> + <time quantity="3" unit="minutes"/> + <method/> +</recipe> +//! [33] + +//! [34] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/recipe[method[empty(step)]] +//! [34] + +//! [35] +declare default element namespace "http://cookbook/namespace"; +doc('cookbook.xml')/cookbook/recipe[not(normalize-space(method))] +//! [35] + +//! [36] +<e>{sum((1, 2, 3))}</e> +//! [36] + +//! [37] +<e>6</e> +//! [37] + +//![38] +declare variable $insertion := "example"; +<p class="important {$insertion} obsolete"/> +//![38] + +//! [39] +<p class="important example obsolete"/> +//! [39] + +//! [40] +declare default element namespace "http://cookbook/namespace"; +let $docURI := 'cookbook.xml' +return if(doc-available($docURI)) + then doc($docURI)//recipe/<oppskrift>{./node()}</oppskrift> + else <oppskrift>Failed to load {$docURI}</oppskrift> +//! [40] + +//! [41] +<span>1</span> +<span>3</span> +<span>5</span> +<span>7</span> +<span>9</span> +<span>b</span> +<span>d</span> +<span>f</span> +//! [41] + +//! [42] +<span>1</span> +//! [42] + +//! [43] +let $doc := doc('doc.txt') +return $doc/doc/p[1]/span[1] +//! [43] + +//! [44] +for $a in doc('doc.txt')/doc/p/span[1] +return $a +//! [44] + +//! [45] +doc('doc.txt')/doc/p/span[1] +//! [45] + +//! [46] +doc('doc.txt')//p/<p>{span/node()}</p> +//! [46] + +//! [47] +<p>78</p> +<p>9a</p> +<p>12</p> +<p>bc</p> +<p>de</p> +<p>34</p> +<p>56</p> +<p>f0</p> +//! [47] + +//! [48] +for $a in doc('doc.txt')//p + return <p>{$a/span/node()}</p> +//! [48] + +//! [49] +<p>12</p> +<p>34</p> +<p>56</p> +<p>78</p> +<p>9a</p> +<p>bc</p> +<p>de</p> +<p>f0</p> +//! [49] + +} + diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp new file mode 100644 index 0000000..0b30c4d --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +return baseURI.resolved(relative); +//! [0] diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp new file mode 100644 index 0000000..5c1a4a0 --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +OutputType inputToOutputItem(const InputType &inputType) const; +//! [0] diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp new file mode 100644 index 0000000..443f825 --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +myInstance = QXmlNodeModelIndex(); +//! [0] + +//! [1] +QFile queryFile(argv[1]); +QFile chemistryData(argv[2]); +QString moleculeName = argv[3]; + +QXmlQuery query; +query.setQuery(&queryFile, QUrl::fromLocalFile(queryFile.fileName())); + +ChemistryNodeModel myNodeModel(query.namePool(), chemistryData); +QXmlNodeModelIndex startNode = myNodeModel.nodeFor(moleculeName); +query.bindVariable("queryRoot", startNode); + +QFile out; +out.open(stdout, QIODevice::WriteOnly); + +QXmlSerializer serializer(query, &out); +query.evaluateTo(&serializer); +//! [1] diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp new file mode 100644 index 0000000..0325851 --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery("doc('index.html')/html/body/p[1]"); + +QXmlSerializer serializer(query, myOutputDevice); +query.evaluateTo(&serializer); +//! [0] diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp new file mode 100644 index 0000000..71363cf --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &ni) const +{ + // Convert the QXmlNodeModelIndex to a value that is specific to what we represent. + const MyValue value = toMyValue(ni); + + switch(axis) + { + case Parent: + return toNodeIndex(value.parent()); + case FirstChild: + case PreviousSibling: + case NextSibling: + // and so on + ; + } + return QXmlNodeModelIndex(); +} +//! [0] diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp new file mode 100644 index 0000000..4512d99 --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery("doc('index.html')/html/body/p[1]"); + +QXmlFormatter formatter(query, myOutputDevice); +formatter.setIndentationDepth(2); +query.evaluateTo(&formatter); +//! [0] diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp new file mode 100644 index 0000000..37274f4 --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Fills the bits from begin to end with 1s and leaves the rest as 0. + +template<typename IntegralT> +inline IntegralT bitmask(IntegralT begin, IntegralT end) +{ + IntegralT filled_bits = (1 << (end - begin + 1)) - 1; + return filled_bits << begin; +} diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp new file mode 100644 index 0000000..dd5cd5b --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QXmlNamePool namePool(query.namePool()); + query.bindVariable(QXmlName(namePool, localName), value); +//! [0] + + +{ +//! [1] + QByteArray myDocument; + QBuffer buffer(&myDocument); // This is a QIODevice. + buffer.open(QIODevice::ReadOnly); + QXmlQuery query; + query.bindVariable("myDocument", &buffer); + query.setQuery("doc($myDocument)"); +//! [1] +} + + +{ + QIODevice *device = 0; +//! [2] + QXmlNamePool namePool(query.namePool()); + query.bindVariable(QXmlName(namePool, localName), device); +//! [2] + +} + +{ + QIODevice *myOutputDevice = 0; +//! [3] + QFile xq("myquery.xq"); + + QXmlQuery query; + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlSerializer serializer(query, myOutputDevice); + query.evaluateTo(&serializer); +//! [3] +} + +{ + QIODevice *myOutputDevice = 0; +//! [4] + QFile xq("myquery.xq"); + QString fileName("the filename"); + QString publisherName("the publisher"); + qlonglong year = 1234; + + QXmlQuery query; + + query.bindVariable("file", QVariant(fileName)); + query.bindVariable("publisher", QVariant(publisherName)); + query.bindVariable("year", QVariant(year)); + + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlSerializer serializer(query, myOutputDevice); + query.evaluateTo(&serializer); +//! [4] +} + +{ +//! [5] + QFile xq("myquery.xq"); + QString fileName("the filename"); + QString publisherName("the publisher"); + qlonglong year = 1234; + + QXmlQuery query; + + query.bindVariable("file", QVariant(fileName)); + query.bindVariable("publisher", QVariant(publisherName)); + query.bindVariable("year", QVariant(year)); + + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlResultItems result; + query.evaluateTo(&result); + QXmlItem item(result.next()); + while (!item.isNull()) { + if (item.isAtomicValue()) { + QVariant v = item.toAtomicValue(); + switch (v.type()) { + case QVariant::LongLong: + // xs:integer + break; + case QVariant::String: + // xs:string + break; + default: + // error + break; + } + } + else if (item.isNode()) { + QXmlNodeModelIndex i = item.toNodeModelIndex(); + // process node + } + item = result.next(); + } +//! [5] +} + +{ +//! [6] + QFile xq("myquery.xq"); + + QXmlQuery query; + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlResultItems result; + query.evaluateTo(&result); + QXmlItem item(result.next()); + while (!item.isNull()) { + if (item.isAtomicValue()) { + QVariant v = item.toAtomicValue(); + switch (v.type()) { + case QVariant::LongLong: + // xs:integer + break; + case QVariant::String: + // xs:string + break; + default: + if (v.userType() == qMetaTypeId<QXmlName>()) { + QXmlName n = qvariant_cast<QXmlName>(v); + // process QXmlName n... + } + else { + // error + } + break; + } + } + else if (item.isNode()) { + QXmlNodeModelIndex i = item.toNodeModelIndex(); + // process node + } + item = result.next(); + } +//! [6] +} + +{ + QIODevice *out = 0; +//! [7] + QXmlQuery query(QXmlQuery::XSLT20); + query.setFocus(QUrl("myInput.xml")); + query.setQuery(QUrl("myStylesheet.xsl")); + query.evaluateTo(out); +//! [7] +} diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp new file mode 100644 index 0000000..c495c0b --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery("<e/>, 1, 'two'"); +QXmlResultItems result; + +if (query.isValid()) { + query.evaluateTo(&result); + QXmlItem item(result.next()); + while (!item.isNull()) { + // use item + item = result.next(); + } + if (result.hasError()) + /* Runtime error! */; +} +//! [0] diff --git a/doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp b/doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp new file mode 100644 index 0000000..0325851 --- /dev/null +++ b/doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery("doc('index.html')/html/body/p[1]"); + +QXmlSerializer serializer(query, myOutputDevice); +query.evaluateTo(&serializer); +//! [0] diff --git a/doc/src/snippets/patternist/anyHTMLElement.xq b/doc/src/snippets/patternist/anyHTMLElement.xq new file mode 100644 index 0000000..9f5ee12 --- /dev/null +++ b/doc/src/snippets/patternist/anyHTMLElement.xq @@ -0,0 +1 @@ +doc('data.xml')/*:body diff --git a/doc/src/snippets/patternist/anyXLinkAttribute.xq b/doc/src/snippets/patternist/anyXLinkAttribute.xq new file mode 100644 index 0000000..059bcc0 --- /dev/null +++ b/doc/src/snippets/patternist/anyXLinkAttribute.xq @@ -0,0 +1,2 @@ +declare namespace xlink = "http://www.w3.org/1999/xlink"; +doc('image.svg')//@xlink:* diff --git a/doc/src/snippets/patternist/bracesIncluded.xq b/doc/src/snippets/patternist/bracesIncluded.xq new file mode 100644 index 0000000..3961c28 --- /dev/null +++ b/doc/src/snippets/patternist/bracesIncluded.xq @@ -0,0 +1 @@ +<e>{sum((1, 2, 3))}</e> diff --git a/doc/src/snippets/patternist/bracesIncludedResult.xml b/doc/src/snippets/patternist/bracesIncludedResult.xml new file mode 100644 index 0000000..0004c71 --- /dev/null +++ b/doc/src/snippets/patternist/bracesIncludedResult.xml @@ -0,0 +1 @@ +<e>6</e> diff --git a/doc/src/snippets/patternist/bracesOmitted.xq b/doc/src/snippets/patternist/bracesOmitted.xq new file mode 100644 index 0000000..ffbadd0 --- /dev/null +++ b/doc/src/snippets/patternist/bracesOmitted.xq @@ -0,0 +1 @@ +<e>sum({(1, 2, 3)})</e> diff --git a/doc/src/snippets/patternist/bracesOmittedResult.xml b/doc/src/snippets/patternist/bracesOmittedResult.xml new file mode 100644 index 0000000..744fb8f --- /dev/null +++ b/doc/src/snippets/patternist/bracesOmittedResult.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<e>sum(1 2 3)</e>
\ No newline at end of file diff --git a/doc/src/snippets/patternist/computedTreeFragment.xq b/doc/src/snippets/patternist/computedTreeFragment.xq new file mode 100644 index 0000000..c5b93ad --- /dev/null +++ b/doc/src/snippets/patternist/computedTreeFragment.xq @@ -0,0 +1,14 @@ +declare default element namespace "http://example.com/Namespace"; +declare variable $documentElementName := "doc"; + +element {$documentElementName} +{ + attribute xml:base {"http://example.com/"}, + element anotherElement + { + comment {" a comment "}, + processing-instruction target {"data"}, + element anotherElement {()}, + text {"some text"} + } +} diff --git a/doc/src/snippets/patternist/copyAttribute.xq b/doc/src/snippets/patternist/copyAttribute.xq new file mode 100644 index 0000000..40e4494 --- /dev/null +++ b/doc/src/snippets/patternist/copyAttribute.xq @@ -0,0 +1,9 @@ +<html> + <body> + <p> + { + doc('feed.rss')/rss/@version + } + </p> + </body> +</html> diff --git a/doc/src/snippets/patternist/copyID.xq b/doc/src/snippets/patternist/copyID.xq new file mode 100644 index 0000000..2409caf --- /dev/null +++ b/doc/src/snippets/patternist/copyID.xq @@ -0,0 +1,3 @@ +(: Copy the value of xml:id attribute from other.html. This is a comment by the way! :) +<html xmlns="http://www.w3.org/1999/xhtml/" + xml:id="{doc("other.html")/html/@xml:id}"/> diff --git a/doc/src/snippets/patternist/directTreeFragment.xq b/doc/src/snippets/patternist/directTreeFragment.xq new file mode 100644 index 0000000..96bc963 --- /dev/null +++ b/doc/src/snippets/patternist/directTreeFragment.xq @@ -0,0 +1,7 @@ +<doc xmlns="http://example.com/Namespace" xml:base="http://example.com/"> + + <!-- a comment --> + <?target data?> + <anotherElement/> + some text +</doc> diff --git a/doc/src/snippets/patternist/doc.txt b/doc/src/snippets/patternist/doc.txt new file mode 100644 index 0000000..d30b057 --- /dev/null +++ b/doc/src/snippets/patternist/doc.txt @@ -0,0 +1,35 @@ +<doc> + <p> + <span>1</span> + <span>2</span> + </p> + <p> + <span>3</span> + <span>4</span> + </p> + <p> + <span>5</span> + <span>6</span> + </p> + <p> + <span>7</span> + <span>8</span> + </p> + <p> + <span>9</span> + <span>a</span> + </p> + <p> + <span>b</span> + <span>c</span> + </p> + <p> + <span>d</span> + <span>e</span> + </p> + <p> + <span>f</span> + <span>0</span> + </p> +</doc> + diff --git a/doc/src/snippets/patternist/docPlainHTML.xq b/doc/src/snippets/patternist/docPlainHTML.xq new file mode 100644 index 0000000..622bec8 --- /dev/null +++ b/doc/src/snippets/patternist/docPlainHTML.xq @@ -0,0 +1 @@ +doc("myPlainHTML.html")/body diff --git a/doc/src/snippets/patternist/docPlainHTML2.xq b/doc/src/snippets/patternist/docPlainHTML2.xq new file mode 100644 index 0000000..5e7fbae --- /dev/null +++ b/doc/src/snippets/patternist/docPlainHTML2.xq @@ -0,0 +1 @@ +doc("myPlainHTML.html")/html/body diff --git a/doc/src/snippets/patternist/embedDataInXHTML.xq b/doc/src/snippets/patternist/embedDataInXHTML.xq new file mode 100644 index 0000000..b513922 --- /dev/null +++ b/doc/src/snippets/patternist/embedDataInXHTML.xq @@ -0,0 +1,10 @@ +declare default element namespace "http://www.w3.org/1999/xhtml"; +<html> + <body> + { + for $i in doc("testResult.xml")/tests/test[@status = "failure"] + order by $i/@name + return <p>{$i/@name}</p> + } + </body> +</html> diff --git a/doc/src/snippets/patternist/embedDataInXHTML2.xq b/doc/src/snippets/patternist/embedDataInXHTML2.xq new file mode 100644 index 0000000..754ddba --- /dev/null +++ b/doc/src/snippets/patternist/embedDataInXHTML2.xq @@ -0,0 +1,10 @@ +declare namespace x = "http://www.w3.org/1998/xhtml"; +<x:html> + <x:body> + { + for $i in doc("testResult.xml")/tests/test[@status = "failure"] + order by $i/@name + return <x:p>{$i/@name}</x:p> + } + </x:body> +</x:html> diff --git a/doc/src/snippets/patternist/emptyParagraphs.xq b/doc/src/snippets/patternist/emptyParagraphs.xq new file mode 100644 index 0000000..6024d28 --- /dev/null +++ b/doc/src/snippets/patternist/emptyParagraphs.xq @@ -0,0 +1 @@ +doc('index.html')//p[string-length(.) = 0] diff --git a/doc/src/snippets/patternist/escapeCurlyBraces.xq b/doc/src/snippets/patternist/escapeCurlyBraces.xq new file mode 100644 index 0000000..669e7c1 --- /dev/null +++ b/doc/src/snippets/patternist/escapeCurlyBraces.xq @@ -0,0 +1,4 @@ +<doc> + This is one left followed by one right curly brace: {{ }} + Here they are again, but with character references: { } +</doc> diff --git a/doc/src/snippets/patternist/escapeStringLiterals.xml b/doc/src/snippets/patternist/escapeStringLiterals.xml new file mode 100644 index 0000000..425ccb0 --- /dev/null +++ b/doc/src/snippets/patternist/escapeStringLiterals.xml @@ -0,0 +1,2 @@ +<p>"I hate quotations" -- Ralph Waldo Emerson" + '"I hate quotations"" -- Ralph Waldo Emerson"', appeared above</p>
\ No newline at end of file diff --git a/doc/src/snippets/patternist/escapeStringLiterals.xq b/doc/src/snippets/patternist/escapeStringLiterals.xq new file mode 100644 index 0000000..4a6054b --- /dev/null +++ b/doc/src/snippets/patternist/escapeStringLiterals.xq @@ -0,0 +1,7 @@ +<p> +{ + """I hate quotations"" -- Ralph Waldo Emerson""", + "
", + '''"I hate quotations"" -- Ralph Waldo Emerson"'', appeared above' +} +</p> diff --git a/doc/src/snippets/patternist/expressionInsideAttribute.xq b/doc/src/snippets/patternist/expressionInsideAttribute.xq new file mode 100644 index 0000000..97f46b1 --- /dev/null +++ b/doc/src/snippets/patternist/expressionInsideAttribute.xq @@ -0,0 +1,2 @@ +declare variable $additionalClass := "example"; +<p class="important {$additionalClass} obsolete"/> diff --git a/doc/src/snippets/patternist/filterOnPath.xq b/doc/src/snippets/patternist/filterOnPath.xq new file mode 100644 index 0000000..d23dfe8 --- /dev/null +++ b/doc/src/snippets/patternist/filterOnPath.xq @@ -0,0 +1,2 @@ +let $doc := doc('doc.txt') +return ($doc/doc/p/span)[1] diff --git a/doc/src/snippets/patternist/filterOnStep.xq b/doc/src/snippets/patternist/filterOnStep.xq new file mode 100644 index 0000000..46b77fa --- /dev/null +++ b/doc/src/snippets/patternist/filterOnStep.xq @@ -0,0 +1,2 @@ +let $doc := doc('doc.txt') +return $doc/doc/p/span[1]
\ No newline at end of file diff --git a/doc/src/snippets/patternist/firstParagraph.xq b/doc/src/snippets/patternist/firstParagraph.xq new file mode 100644 index 0000000..db5e2c7 --- /dev/null +++ b/doc/src/snippets/patternist/firstParagraph.xq @@ -0,0 +1 @@ +doc("index.html")/html/body/p[@xml:id = "thatSpecialOne"] diff --git a/doc/src/snippets/patternist/fnStringOnAttribute.xq b/doc/src/snippets/patternist/fnStringOnAttribute.xq new file mode 100644 index 0000000..b26e9f2 --- /dev/null +++ b/doc/src/snippets/patternist/fnStringOnAttribute.xq @@ -0,0 +1,9 @@ +<html> + <body> + <p> + { + string(doc('feed.rss')/rss/@version) + } + </p> + </body> +</html> diff --git a/doc/src/snippets/patternist/forClause.xq b/doc/src/snippets/patternist/forClause.xq new file mode 100644 index 0000000..a412dca --- /dev/null +++ b/doc/src/snippets/patternist/forClause.xq @@ -0,0 +1,3 @@ +for $i in(reverse(1 to 10)), + $d in xs:integer(doc("numbers.xml")/numbers/number) +return ($i + $d) diff --git a/doc/src/snippets/patternist/forClause2.xq b/doc/src/snippets/patternist/forClause2.xq new file mode 100644 index 0000000..4fa505d --- /dev/null +++ b/doc/src/snippets/patternist/forClause2.xq @@ -0,0 +1,3 @@ +for $i in(reverse(1 to 10)), + $d in xs:integer(doc("numbers.xml")/numbers/number) +return $i + $d diff --git a/doc/src/snippets/patternist/forClauseOnFeed.xq b/doc/src/snippets/patternist/forClauseOnFeed.xq new file mode 100644 index 0000000..9ec3339 --- /dev/null +++ b/doc/src/snippets/patternist/forClauseOnFeed.xq @@ -0,0 +1,6 @@ +for $item in doc('feed.rss')//item +return <p> + { + $item/description/node() + } + </p> diff --git a/doc/src/snippets/patternist/indented.xml b/doc/src/snippets/patternist/indented.xml new file mode 100644 index 0000000..a312c63 --- /dev/null +++ b/doc/src/snippets/patternist/indented.xml @@ -0,0 +1,5 @@ +<a> + <b/> + <c/> + <p>Some Text</p> +</a> diff --git a/doc/src/snippets/patternist/introAcneRemover.xq b/doc/src/snippets/patternist/introAcneRemover.xq new file mode 100644 index 0000000..4e6ee80 --- /dev/null +++ b/doc/src/snippets/patternist/introAcneRemover.xq @@ -0,0 +1,8 @@ +<result> + <para>The following skin care products have shipped, ordered by shipping date(oldest first):</para> + { + for $i in doc("myOrders.xml")/orders/order[@product = "Acme Skin Care"] + order by xs:date($i/@shippingDate) descending + return $i + } +</result> diff --git a/doc/src/snippets/patternist/introExample2.xq b/doc/src/snippets/patternist/introExample2.xq new file mode 100644 index 0000000..411cc17 --- /dev/null +++ b/doc/src/snippets/patternist/introExample2.xq @@ -0,0 +1,5 @@ +<bibliography> +{ + doc($file)/bib/book[publisher = $publisher and @year > $year]/<book year="{@year}">{title}</book> +} +</bibliography> diff --git a/doc/src/snippets/patternist/introFileHierarchy.xml b/doc/src/snippets/patternist/introFileHierarchy.xml new file mode 100644 index 0000000..cfa6151 --- /dev/null +++ b/doc/src/snippets/patternist/introFileHierarchy.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<directory name="home"> + + <file name="myNote.txt" mimetype="text/plain" size="8" extension="txt" uri="file:///home/frans/myNote.txt"> + <content asBase64Binary="TXkgTm90ZSE=" asStringFromUTF-8="My Note!"/> + </file> + + <directory name="src"> + ... + </directory> + + ... + +</directory> diff --git a/doc/src/snippets/patternist/introNavigateFS.xq b/doc/src/snippets/patternist/introNavigateFS.xq new file mode 100644 index 0000000..1f5a3a7 --- /dev/null +++ b/doc/src/snippets/patternist/introNavigateFS.xq @@ -0,0 +1,12 @@ +declare variable $myRoot := <e/>; (: This line is a dummy and shouldn't appear in the documentation. :) +<html> + <body> + { + $myRoot//file[@mimetype = 'text/xml' or @mimetype = 'application/xml'] + / + (if(doc-available(@uri)) + then () + else <p>Failed to parse file {@uri}.</p>) + } + </body> +</html> diff --git a/doc/src/snippets/patternist/introductionExample.xq b/doc/src/snippets/patternist/introductionExample.xq new file mode 100644 index 0000000..1a309dd --- /dev/null +++ b/doc/src/snippets/patternist/introductionExample.xq @@ -0,0 +1,3 @@ +<bibliography> +{doc("library.xml")/bib/book[publisher="Addison-Wesley" and @year>1991]/<book year="{@year}">{title}</book>} +</bibliography> diff --git a/doc/src/snippets/patternist/invalidLetOrderBy.xq b/doc/src/snippets/patternist/invalidLetOrderBy.xq new file mode 100644 index 0000000..d65f240 --- /dev/null +++ b/doc/src/snippets/patternist/invalidLetOrderBy.xq @@ -0,0 +1,3 @@ +let $i := (2, 3, 1) +order by $i[1] +return $i diff --git a/doc/src/snippets/patternist/items.xq b/doc/src/snippets/patternist/items.xq new file mode 100644 index 0000000..0b46ec1 --- /dev/null +++ b/doc/src/snippets/patternist/items.xq @@ -0,0 +1,5 @@ +<aNode/>, +xs:base64Binary("FFFF"), +current-date(), +3e3, (: A floating point value :) +attribute {"name"} {()} diff --git a/doc/src/snippets/patternist/letOrderBy.xq b/doc/src/snippets/patternist/letOrderBy.xq new file mode 100644 index 0000000..f4106d2 --- /dev/null +++ b/doc/src/snippets/patternist/letOrderBy.xq @@ -0,0 +1,4 @@ +for $a in (8, -4, 2) +let $b := ($a * -1, $a) +order by $a +return $b diff --git a/doc/src/snippets/patternist/literalsAndOperators.xq b/doc/src/snippets/patternist/literalsAndOperators.xq new file mode 100644 index 0000000..ec4af33 --- /dev/null +++ b/doc/src/snippets/patternist/literalsAndOperators.xq @@ -0,0 +1,2 @@ +declare variable $date := fn:current-date(); (: This line should not be part of the example. It exists in order to make the query valid. :) +fn:current-date() - $date > xs:dayTimeDuration("P365D") diff --git a/doc/src/snippets/patternist/mobeyDick.xml b/doc/src/snippets/patternist/mobeyDick.xml new file mode 100644 index 0000000..32d0b6c --- /dev/null +++ b/doc/src/snippets/patternist/mobeyDick.xml @@ -0,0 +1,4 @@ +<book xmlns:dc='http://purl.org/dc/elements/1.1' + xmlns='http://example.com/MyDefault'> + <dc:title>Mobey Dick</dc:title> ... +</book> diff --git a/doc/src/snippets/patternist/nextLastParagraph.xq b/doc/src/snippets/patternist/nextLastParagraph.xq new file mode 100644 index 0000000..9424f79 --- /dev/null +++ b/doc/src/snippets/patternist/nextLastParagraph.xq @@ -0,0 +1 @@ +doc('index.html')//p[last() - 1] diff --git a/doc/src/snippets/patternist/nodeConstructorsAreExpressions.xq b/doc/src/snippets/patternist/nodeConstructorsAreExpressions.xq new file mode 100644 index 0000000..ce36e84 --- /dev/null +++ b/doc/src/snippets/patternist/nodeConstructorsAreExpressions.xq @@ -0,0 +1,4 @@ +let $docURI := 'maybeNotWellformed.xml' +return if(doc-available($docURI)) + then doc($docURI)//p/<para>{./node()}</para> + else <para>Failed to load {$docURI}</para> diff --git a/doc/src/snippets/patternist/nodeConstructorsInPaths.xq b/doc/src/snippets/patternist/nodeConstructorsInPaths.xq new file mode 100644 index 0000000..beb294f --- /dev/null +++ b/doc/src/snippets/patternist/nodeConstructorsInPaths.xq @@ -0,0 +1 @@ +doc('feed.rss')//item/<p>{description/node()}</p> diff --git a/doc/src/snippets/patternist/nodeTestChildElement.xq b/doc/src/snippets/patternist/nodeTestChildElement.xq new file mode 100644 index 0000000..7aa7b34 --- /dev/null +++ b/doc/src/snippets/patternist/nodeTestChildElement.xq @@ -0,0 +1 @@ +doc('index.html')/descendant-or-self::element(p)/child::element(span) diff --git a/doc/src/snippets/patternist/notIndented.xml b/doc/src/snippets/patternist/notIndented.xml new file mode 100644 index 0000000..b3321f2 --- /dev/null +++ b/doc/src/snippets/patternist/notIndented.xml @@ -0,0 +1 @@ +<a><b/><c/><p>Some Text</p></a> diff --git a/doc/src/snippets/patternist/oneElementConstructor.xq b/doc/src/snippets/patternist/oneElementConstructor.xq new file mode 100644 index 0000000..b7eb615 --- /dev/null +++ b/doc/src/snippets/patternist/oneElementConstructor.xq @@ -0,0 +1 @@ +<myElement/> diff --git a/doc/src/snippets/patternist/paragraphsExceptTheFiveFirst.xq b/doc/src/snippets/patternist/paragraphsExceptTheFiveFirst.xq new file mode 100644 index 0000000..16438d1 --- /dev/null +++ b/doc/src/snippets/patternist/paragraphsExceptTheFiveFirst.xq @@ -0,0 +1 @@ +doc('index.html')//p[position() > 5] diff --git a/doc/src/snippets/patternist/paragraphsWithTables.xq b/doc/src/snippets/patternist/paragraphsWithTables.xq new file mode 100644 index 0000000..dbb9fcf --- /dev/null +++ b/doc/src/snippets/patternist/paragraphsWithTables.xq @@ -0,0 +1 @@ +doc('index.html')/html/body/p[table] diff --git a/doc/src/snippets/patternist/pathAB.xq b/doc/src/snippets/patternist/pathAB.xq new file mode 100644 index 0000000..26fd1e5 --- /dev/null +++ b/doc/src/snippets/patternist/pathAB.xq @@ -0,0 +1 @@ +doc('index.html')//p/span diff --git a/doc/src/snippets/patternist/pathsAllParagraphs.xq b/doc/src/snippets/patternist/pathsAllParagraphs.xq new file mode 100644 index 0000000..ba47900 --- /dev/null +++ b/doc/src/snippets/patternist/pathsAllParagraphs.xq @@ -0,0 +1 @@ +doc('index.html')//p diff --git a/doc/src/snippets/patternist/simpleHTML.xq b/doc/src/snippets/patternist/simpleHTML.xq new file mode 100644 index 0000000..93ac31e --- /dev/null +++ b/doc/src/snippets/patternist/simpleHTML.xq @@ -0,0 +1 @@ +doc("index.html")/html/body/p[@class="example"] diff --git a/doc/src/snippets/patternist/simpleXHTML.xq b/doc/src/snippets/patternist/simpleXHTML.xq new file mode 100644 index 0000000..fda5371 --- /dev/null +++ b/doc/src/snippets/patternist/simpleXHTML.xq @@ -0,0 +1,2 @@ +declare namespace x = "http://www.w3.org/1999/xhtml/"; +doc("index.html")/x:html/x:body/x:p[@class="example"] diff --git a/doc/src/snippets/patternist/svgDocumentElement.xml b/doc/src/snippets/patternist/svgDocumentElement.xml new file mode 100644 index 0000000..0c7be4e --- /dev/null +++ b/doc/src/snippets/patternist/svgDocumentElement.xml @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg"/> diff --git a/doc/src/snippets/patternist/tablesInParagraphs.xq b/doc/src/snippets/patternist/tablesInParagraphs.xq new file mode 100644 index 0000000..fc92cf0 --- /dev/null +++ b/doc/src/snippets/patternist/tablesInParagraphs.xq @@ -0,0 +1 @@ +doc('index.html')/html/body/p/table diff --git a/doc/src/snippets/patternist/twoSVGElements.xq b/doc/src/snippets/patternist/twoSVGElements.xq new file mode 100644 index 0000000..ab4fe35 --- /dev/null +++ b/doc/src/snippets/patternist/twoSVGElements.xq @@ -0,0 +1,5 @@ +declare namespace s = "http://www.w3.org/2000/svg"; +declare default element namespace "http://www.w3.org/2000/svg"; +let $doc := doc('image.svg') +return ($doc/svg, + $doc/s:svg) diff --git a/doc/src/snippets/patternist/xmlStylesheet.xq b/doc/src/snippets/patternist/xmlStylesheet.xq new file mode 100644 index 0000000..9e02208 --- /dev/null +++ b/doc/src/snippets/patternist/xmlStylesheet.xq @@ -0,0 +1 @@ +<?xml-stylesheet type="test/xsl" href="formatter.xsl"?> diff --git a/doc/src/snippets/patternist/xsBooleanTrue.xq b/doc/src/snippets/patternist/xsBooleanTrue.xq new file mode 100644 index 0000000..897a99e --- /dev/null +++ b/doc/src/snippets/patternist/xsBooleanTrue.xq @@ -0,0 +1 @@ +xs:boolean("true") diff --git a/doc/src/snippets/patternist/xsvgDocumentElement.xml b/doc/src/snippets/patternist/xsvgDocumentElement.xml new file mode 100644 index 0000000..fb6a236 --- /dev/null +++ b/doc/src/snippets/patternist/xsvgDocumentElement.xml @@ -0,0 +1 @@ +<x:svg xmlns:x="http://www.w3.org/2000/svg"/> diff --git a/doc/src/snippets/qxmlquery/bindingExample.cpp b/doc/src/snippets/qxmlquery/bindingExample.cpp new file mode 100644 index 0000000..62e19be --- /dev/null +++ b/doc/src/snippets/qxmlquery/bindingExample.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QBuffer device; + device.setData(myQString.toUtf8()); + device.open(QIODevice::ReadOnly); + + QXmlQuery query; + query.setQuery("doc($inputDocument)/query[theDocument]"); + query.bindVariable("inputDocument", &device); +//! [0] diff --git a/doc/src/snippets/qxmlschema/main.cpp b/doc/src/snippets/qxmlschema/main.cpp new file mode 100644 index 0000000..ddc1c16 --- /dev/null +++ b/doc/src/snippets/qxmlschema/main.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <QtXmlPatterns> + +class Schema +{ + public: + void loadFromUrl() const; + void loadFromFile() const; + void loadFromData() const; +}; + +void Schema::loadFromUrl() const +{ +//! [0] + QUrl url("http://www.schema-example.org/myschema.xsd"); + + QXmlSchema schema; + if (schema.load(url) == true) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [0] +} + +void Schema::loadFromFile() const +{ +//! [1] + QFile file("myschema.xsd"); + file.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&file, QUrl::fromLocalFile(file.fileName())); + + if (schema.isValid()) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [1] +} + +void Schema::loadFromData() const +{ +//! [2] + QByteArray data( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://qt.nokia.com/xmlschematest\"" + " targetNamespace=\"http://qt.nokia.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + "</xsd:schema>" ); + + QXmlSchema schema; + schema.load(data); + + if (schema.isValid()) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [2] +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + Schema schema; + + schema.loadFromUrl(); + schema.loadFromFile(); + schema.loadFromData(); + + return 0; +} diff --git a/doc/src/snippets/qxmlschemavalidator/main.cpp b/doc/src/snippets/qxmlschemavalidator/main.cpp new file mode 100644 index 0000000..bf88e71 --- /dev/null +++ b/doc/src/snippets/qxmlschemavalidator/main.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <QtXmlPatterns> + +class SchemaValidator +{ + public: + void validateFromUrl() const; + void validateFromFile() const; + void validateFromData() const; + void validateComplete() const; + + private: + QXmlSchema getSchema() const; +}; + +void SchemaValidator::validateFromUrl() const +{ +//! [0] + const QXmlSchema schema = getSchema(); + + const QUrl url("http://www.schema-example.org/test.xml"); + + QXmlSchemaValidator validator(schema); + if (validator.validate(url)) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [0] +} + +void SchemaValidator::validateFromFile() const +{ +//! [1] + const QXmlSchema schema = getSchema(); + + QFile file("test.xml"); + file.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&file, QUrl::fromLocalFile(file.fileName()))) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [1] +} + +void SchemaValidator::validateFromData() const +{ +//! [2] + const QXmlSchema schema = getSchema(); + + QByteArray data("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<test></test>"); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&buffer)) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [2] +} + +QXmlSchema SchemaValidator::getSchema() const +{ + QByteArray data("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<xsd:schema" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns=\"http://qt.nokia.com/xmlschematest\"" + " targetNamespace=\"http://qt.nokia.com/xmlschematest\"" + " version=\"1.0\"" + " elementFormDefault=\"qualified\">" + "</xsd:schema>"); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&buffer); + + return schema; +} + +void SchemaValidator::validateComplete() const +{ +//! [3] + QUrl schemaUrl("file:///home/user/schema.xsd"); + + QXmlSchema schema; + schema.load(schemaUrl); + + if (schema.isValid()) { + QFile file("test.xml"); + file.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&file, QUrl::fromLocalFile(file.fileName()))) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; + } +//! [3] +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + SchemaValidator validator; + + validator.validateFromUrl(); + validator.validateFromFile(); + validator.validateFromData(); + validator.validateComplete(); + + return 0; +} diff --git a/doc/src/xml-processing/xml-patterns.qdoc b/doc/src/xml-processing/xml-patterns.qdoc new file mode 100644 index 0000000..1c8c90c --- /dev/null +++ b/doc/src/xml-processing/xml-patterns.qdoc @@ -0,0 +1,889 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page xmlprocessing.html + \title XQuery + + \previouspage Working with the DOM Tree + \contentspage XML Processing + + \keyword Patternist + + \brief An overview of Qt's support for using XML technologies in + Qt programs. + + \tableofcontents + + \section1 Introduction + + XQuery is a language for traversing XML documents to select and + aggregate items of interest and to transform them for output as + XML or some other format. XPath is the \e{element selection} part + of XQuery. + + The QtXmlPatterns module supports using + \l{http://www.w3.org/TR/xquery} {XQuery 1.0} and + \l{http://www.w3.org/TR/xpath20} {XPath 2.0} in Qt applications, + for querying XML data \e{and} for querying + \l{QAbstractXmlNodeModel} {non-XML data that can be modeled to + look like XML}. + Readers who are not familiar with the XQuery/XPath language can read + \l {A Short Path to XQuery} for a brief introduction. + + \section1 Advantages of using QtXmlPatterns and XQuery + + The XQuery/XPath language simplifies data searching and + transformation tasks by eliminating the need for doing a lot of + C++ or Java procedural programming for each new query task. Here + is an XQuery that constructs a bibliography of the contents of a + library: + + \target qtxmlpatterns_example_query + \quotefile snippets/patternist/introductionExample.xq + + First, the query opens a \c{<bibliography>} element in the + output. The + \l{xquery-introduction.html#using-path-expressions-to-match-and-select-items} + {embedded path expression} then loads the XML document describing + the contents of the library (\c{library.xml}) and begins the + search. For each \c{<book>} element it finds, where the publisher + was Addison-Wesley and the publication year was after 1991, it + creates a new \c{<book>} element in the output as a child of the + open \c{<bibliography>} element. Each new \c{<book>} element gets + the book's title as its contents and the book's publication year + as an attribute. Finally, the \c{<bibliography>} element is + closed. + + The advantages of using QtXmlPatterns and XQuery in your Qt + programs are summarized as follows: + + \list + + \o \bold{Ease of development}: All the C++ programming required to + perform data query tasks can be replaced by a simple XQuery + like the example above. + + \o \bold{Comprehensive functionality}: The + \l{http://www.w3.org/TR/xquery/#id-expressions} {expression + syntax} and rich set of + \l{http://www.w3.org/TR/xpath-functions} {functions and + operators} provided by XQuery are sufficient for performing any + data searching, selecting, and sorting tasks. + + \o \bold{Conformance to standards}: Conformance to all applicable + XML and XQuery standards ensures that QtXmlPatterns can always + process XML documents generated by other conformant + applications, and that XML documents created with QtXmlPatterns + can be processed by other conformant applications. + + \o \bold{Maximal flexibility} The QtXmlPatterns module can be used + to query XML data \e{and} non-XML data that can be + \l{QAbstractXmlNodeModel} {modeled to look like XML}. + + \endlist + + \section1 Using the QtXmlPatterns module + + There are two ways QtXmlPatterns can be used to evaluate queries. + You can run the query engine in your Qt application using the + QtXmlPatterns C++ API, or you can run the query engine from the + command line using Qt's \c{xmlpatterns} command line utility. + + \section2 Running the query engine from your Qt application + + If we save the example XQuery shown above in a text file (e.g. + \c{myquery.xq}), we can run it from a Qt application using a + standard QtXmlPatterns code sequence: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 3 + + First construct a QFile for the text file containing the XQuery + (\c{myquery.xq}). Then create an instance of QXmlQuery and call + its \l{QXmlQuery::}{setQuery()} function to load and parse the + XQuery file. Then create an \l{QXmlSerializer} {XML serializer} to + output the query's result set as unformatted XML. Finally, call + the \l{QXmlQuery::}{evaluateTo()} function to evaluate the query + and serialize the results as XML. + + \note If you compile Qt yourself, the QtXmlPatterns module will + \e{not} be built if exceptions are disabled, or if you compile Qt + with a compiler that doesn't support member templates, e.g., MSVC + 6. + + See the QXmlQuery documentation for more information about the + QtXmlPatterns C++ API. + + \section2 Running the query engine from the command line utility + + \e xmlpatterns is a command line utility for running XQueries. It + expects the name of a file containing the XQuery text. + + \snippet doc/src/snippets/code/doc_src_qtxmlpatterns.qdoc 2 + + The XQuery in \c{myQuery.xq} will be evaluated and its output + written to \c stdout. Pass the \c -help switch to get the list of + input flags and their meanings. + + xmlpatterns can be used in scripting. However, the descriptions + and messages it outputs were not meant to be parsed and may be + changed in future releases of Qt. + + \target QtXDM + \section1 The XQuery Data Model + + XQuery represents data items as \e{atomic values} or \e{nodes}. An + atomic value is a value in the domain of one of the + \l{http://www.w3.org/TR/xmlschema-2/#built-in-datatypes} {built-in + datatypes} defined in \l{http://www.w3.org/TR/xmlschema-2} {Part + 2} of the W3C XML Schema. A node is normally an XML element or + attribute, but when non-XML data is \l{QAbstractXmlNodeModel} + {modeled to look like XML}, a node can also represent a non-XML + data items. + + When you run an XQuery using the C++ API in a Qt application, you + will often want to bind program variables to $variables in the + XQuery. After the query is evaluated, you will want to interpret + the sequence of data items in the result set. + + \section2 Binding program variables to XQuery variables + + When you want to run a parameterized XQuery from your Qt + application, you will need to \l{QXmlQuery::bindVariable()} {bind + variables} in your program to $name variables in your XQuery. + + Suppose you want to parameterize the bibliography XQuery in the + example above. You could define variables for the catalog that + contains the library (\c{$file}), the publisher name + (\c{$publisher}), and the year of publication (\c{$year}): + + \target qtxmlpatterns_example_query2 + \quotefile snippets/patternist/introExample2.xq + + Modify the QtXmlPatterns code to use one of the \l{QXmlQuery::} + {bindVariable()} functions to bind a program variable to each + XQuery $variable: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 4 + + Each program variable is passed to QtXmlPatterns as a QVariant of + the type of the C++ variable or constant from which it is + constructed. Note that QtXmlPatterns assumes that the type of the + QVariant in the bindVariable() call is the correct type, so the + $variable it is bound to must be used in the XQuery accordingly. + The following table shows how QVariant types are mapped to XQuery + $variable types: + + \table + + \header + \o QVariant type + \o XQuery $variable type + + \row + \o QVariant::LongLong + \o \c xs:integer + + \row + \o QVariant::Int + \o \c xs:integer + + \row + \o QVariant::UInt + \o \c xs:nonNegativeInteger + + \row + \o QVariant::ULongLong + \o \c xs:unsignedLong + + \row + \o QVariant::String + \o \c xs:string + + \row + \o QVariant::Double + \o \c xs:double + + \row + \o QVariant::Bool + \o \c xs:boolean + + \row + \o QVariant::Double + \o \c xs:decimal + + \row + \o QVariant::ByteArray + \o \c xs:base64Binary + + \row + \o QVariant::StringList + \o \c xs:string* + + \row + \o QVariant::Url + \o \c xs:string + + \row + \o QVariant::Date + \o \c xs:date. + + \row + \o QVariant::DateTime + \o \c xs:dateTime + + \row + \o QVariant::Time. + \o \c xs:time. (see \l{Binding To Time}{Binding To + QVariant::Time} below) + + \row + \o QVariantList + \o (see \l{Binding To QVariantList}{Binding To QVariantList} + below) + + \endtable + + A type not shown in the table is not supported and will cause + undefined XQuery behavior or a $variable binding error, depending + on the context in the XQuery where the variable is used. + + \target Binding To Time + \section3 Binding To QVariant::Time + + Because the instance of QTime used in QVariant::Time does not + include a zone offset, an instance of QVariant::Time should not be + bound to an XQuery variable of type \c xs:time, unless the QTime is + UTC. When binding a non-UTC QTime to an XQuery variable, it should + first be passed as a string, or converted to a QDateTime with an arbitrary + date, and then bound to an XQuery variable of type \c xs:dateTime. + + \target Binding To QVariantList + \section3 Binding To QVariantList + + A QVariantList can be bound to an XQuery $variable. All the + \l{QVariant}s in the list must be of the same atomic type, and the + $variable the variant list is bound to must be of that same atomic + type. If the QVariants in the list are not all of the same atomic + type, the XQuery behavior is undefined. + + \section2 Interpreting XQuery results + + When the results of an XQuery are returned in a sequence of \l + {QXmlResultItems} {result items}, atomic values in the sequence + are treated as instances of QVariant. Suppose that instead of + serializing the results of the XQuery as XML, we process the + results programatically. Modify the standard QtXmlPatterns code + sequence to call the overload of QXmlQuery::evaluateTo() that + populates a sequence of \l {QXmlResultItems} {result items} with + the XQuery results: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 5 + + Iterate through the \l {QXmlResultItems} {result items} and test + each QXmlItem to see if it is an atomic value or a node. If it is + an atomic value, convert it to a QVariant with \l {QXmlItem::} + {toAtomicValue()} and switch on its \l {QVariant::type()} {variant + type} to handle all the atomic values your XQuery might return. + The following table shows the QVariant type to expect for each + atomic value type (or QXmlName): + + \table + + \header + \o XQuery result item type + \o QVariant type returned + + \row + \o \c xs:QName + \o QXmlName (see \l{Handling QXmlNames}{Handling QXmlNames} + below) + + \row + \o \c xs:integer + \o QVariant::LongLong + + \row + \o \c xs:string + \o QVariant::String + + \row + \o \c xs:string* + \o QVariant::StringList + + \row + \o \c xs:double + \o QVariant::Double + + \row + \o \c xs:float + \o QVariant::Double + + \row + \o \c xs:boolean + \o QVariant::Bool + + \row + \o \c xs:decimal + \o QVariant::Double + + \row + \o \c xs:hexBinary + \o QVariant::ByteArray + + \row + \o \c xs:base64Binary + \o QVariant::ByteArray + + \row + \o \c xs:gYear + \o QVariant::DateTime + + \row + \o \c xs:gYearMonth + \o QVariant::DateTime + + \row + \o \c xs:gMonthDay + \o QVariant::DateTime + + \row + \o \c xs:gDay + \o QVariant::DateTime + + \row + \o \c xs:gMonth + \o QVariant::DateTime + + \row + \o \c xs:anyURI + \o QVariant::Url + + \row + \o \c xs:untypedAtomic + \o QVariant::String + + \row + \o \c xs:ENTITY + \o QVariant::String + + \row + \o \c xs:date + \o QVariant::DateTime + + \row + \o \c xs:dateTime + \o QVariant::DateTime + + \row + \o \c xs:time + \o (see \l{xstime-not-mapped}{No mapping for xs:time} below) + + \endtable + + \target Handling QXmlNames + \section3 Handling QXmlNames + + If your XQuery can return atomic value items of type \c{xs:QName}, + they will appear in your QXmlResultItems as instances of QXmlName. + Since the QVariant class does not support the QXmlName class + directly, extracting them from QXmlResultItems requires a bit of + slight-of-hand using the \l{QMetaType} {Qt metatype system}. We + must modify our example to use a couple of template functions, a + friend of QMetaType (qMetaTypeId<T>()) and a friend of QVariant + (qvariant_cast<T>()): + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 6 + + To access the strings in a QXmlName returned by an + \l{QXmlQuery::evaluateTo()} {XQuery evaluation}, the QXmlName must + be accessed with the \l{QXmlNamePool} {name pool} from the + instance of QXmlQuery that was used for the evaluation. + + \target xstime-not-mapped + \section3 No mapping for xs:time + + An instance of \c xs:time can't be represented correctly as an + instance of QVariant::Time, unless the \c xs:time is a UTC time. + This is because xs:time has a zone offset (0 for UTC) in addition + to the time value, which the QTime in QVariant::Time does not + have. This means that if an XQuery tries to return an atomic value + of type \c xs:time, an invalid QVariant will be returned. A query + can return an atomic value of type xs:time by either converting it + to an \c xs:dateTime with an arbitrary date, or to an \c xs:string. + + \section1 Using XQuery with Non-XML Data + + Although the XQuery language was designed for querying XML, with + QtXmlPatterns one can use XQuery for querying any data that can + be modeled to look like XML. Non-XML data is modeled to look like + XML by loading it into a custom subclass of QAbstractXmlNodeModel, + where it is then presented to the QtXmlPatterns XQuery engine via + the same API the XQuery engine uses for querying XML. + + When QtXmlPatterns loads and queries XML files and produces XML + output, it can always load the XML data into its default XML node + model, where it can be traversed efficiently. The XQuery below + traverses the product orders found in the XML file \e myOrders.xml + to find all the skin care product orders and output them ordered + by shipping date. + + \quotefile snippets/patternist/introAcneRemover.xq + + QtXmlPatterns can be used out of the box to perform this + query, provided \e myOrders.xml actually contains well-formed XML. It + can be loaded directly into the default XML node model and + traversed. But suppose we want QtXmlPatterns to perform queries on + the hierarchical structure of the local file system. The default + XML node model in QtXmlPatterns is not suitable for navigating the + file system, because there is no XML file to load that contains a + description of it. Such an XML file, if it existed, might look + something like this: + + \quotefile snippets/patternist/introFileHierarchy.xml + + The \l{File System Example}{File System Example} does exactly this. + + There is no such file to load into the default XML node model, but + one can write a subclass of QAbstractXmlNodeModel to represent the + file system. This custom XML node model, once populated with all + the directory and file descriptors obtained directly from the + system, presents the complete file system hierarchy to the query + engine via the same API used by the default XML node model to + present the contents of an XML file. In other words, once the + custom XML node model is populated, it presents the file system to + the query engine as if a description of it had been loaded into + the default XML node model from an XML file like the one shown + above. + + Now we can write an XQuery to find all the XML files and parse + them to find the ones that don't contain well-formed XML. + + \quotefromfile snippets/patternist/introNavigateFS.xq + \skipto <html> + \printuntil + + Without QtXmlPatterns, there is no simple way to solve this kind + of problem. You might do it by writing a C++ program to traverse + the file system, sniff out all the XML files, and submit each one + to an XML parser to test that it contains valid XML. The C++ code + required to write that program will probably be more complex than + the C++ code required to subclass QAbstractXmlNodeModel, but even + if the two are comparable, your custom C++ program can be used + only for that one task, while your custom XML node model can be + used by any XQuery that must navigate the file system. + + The general approach to using XQuery to perform queries on non-XML + data has been a three step process. In the first step, the data is + loaded into a non-XML data model. In the second step, the non-XML + data model is serialized as XML and output to XML (text) files. In + the final step, an XML tool loads the XML files into a second, XML + data model, where the XQueries can be performed. The development + cost of implementing this process is often high, and the three + step system that results is inefficient because the two data + models must be built and maintained separately. + + With QtXmlPatterns, subclassing QAbstractXmlNodeModel eliminates + the transformation required to convert the non-XML data model to + the XML data model, because there is only ever one data model + required. The non-XML data model presents the non-XML data to the + query engine via the XML data model API. Also, since the query + engine uses the API to access the QAbstractXmlNodeModel, the data + model subclass can construct the elements, attributes and other + data on demand, responding to the query's specific requests. This + can greatly improve efficiency, because it means the entire model + might not have to be built. For example, in the file system model + above, it is not necessary to build an instance for a whole + XML file representing the whole file system. Instead nodes are + created on demand, which also likely is a small subset of the file + system. + + Examples of other places where XQuery could be used in + QtXmlPatterns to query non-XML data: + + \list + + \o The internal representation for word processor documents + + \o The set of dependencies for a software build system + + \o The hierarchy (or graph) that links a set of HTML documents + from a web crawler + + \o The images and meta-data in an image collection + + \o The set of D-Bus interfaces available in a system + + \o A QObject hierarchy, as seen in the \l{QObject XML Model + Example} {QObject XML Model example}. + + \endlist + + See the QAbstractXmlNodeModel documentation for information about + how to implement custom XML node models. + + \section1 More on using QtXmlPatterns with non-XML Data + + Subclassing QAbstractXmlNodeModel to let the query engine access + non-XML data by the same API it uses for XML is the feature that + enables QtXmlPatterns to query non-XML data with XQuery. It allows + XQuery to be used as a mapping layer between different non-XML + node models or between a non-XML node model and the built-in XML + node model. Once the subclass(es) of QAbstractXmlNodeModel have + been written, XQuery can be used to select a set of elements from + one node model, transform the selected elements, and then write + them out, either as XML using QXmlQuery::evaluateTo() and QXmlSerializer, + or as some other format using a subclass of QAbstractXmlReceiver. + + Consider a word processor application that must import and export + data in several different formats. Rather than writing a lot of + C++ code to convert each input format to an intermediate form, and + more C++ code to convert the intermediate form back to each + output format, one can implement a solution based on QtXmlPatterns + that uses simple XQueries to transform each XML or non-XML format + (e.g. MathFormula.xml below) to the intermediate form (e.g. the + DocumentRepresentation node model class below), and more simple + XQueries to transform the intermediate form back to each XML or + non-XML format. + + \image patternist-wordProcessor.png + + Because CSV files are not XML, a subclass of QAbstractXmlNodeModel + is used to present the CSV data to the XQuery engine as if it were + XML. What are not shown are the subclasses of QAbstractXmlReceiver + that would then send the selected elements into the + DocumentRepresentation node model, and the subclasses of + QAbstractXmlNodeModel that would ultimately write the output files + in each format. + + \section1 Security Considerations + + \section2 Code Injection + + XQuery is vulnerable to + \l{http://en.wikipedia.org/wiki/Code_injection} {code injection + attacks} in the same way as the SQL language. If an XQuery is + constructed by concatenating strings, and the strings come from + user input, the constructed XQuery could be malevolent. The best + way to prevent code injection attacks is to not construct XQueries + from user-written strings, but only accept user data input using + QVariant and variable bindings. See QXmlQuery::bindVariable(). + + The articles + \l{http://www.ibm.com/developerworks/xml/library/x-xpathinjection.html} + {Avoid the dangers of XPath injection}, by Robi Sen and + \l{http://www.packetstormsecurity.org/papers/bypass/Blind_XPath_Injection_20040518.pdf} + {Blind XPath Injection}, by Amit Klein, discuss the XQuery code + injection problem in more detail. + + \section2 Denial of Service Attacks + + Applications using QtXmlPatterns are subject to the same + limitations of software as other systems. Generally, these can not + be checked. This means QtXmlPatterns does not prevent rogue + queries from consuming too many resources. For example, a query + could take too much time to execute or try to transfer too much + data. A query could also do too much recursion, which could crash + the system. XQueries can do these things accidentally, but they + can also be done as deliberate denial of service attacks. + + \section1 Features and Conformance + + \section2 XQuery 1.0 + + QtXmlPatterns aims at being a + \l{http://www.w3.org/TR/xquery/#id-xquery-conformance} {conformant + XQuery processor}. It adheres to + \l{http://www.w3.org/TR/xquery/#id-minimal-conformance} {Minimal + Conformance} and supports the + \l{http://www.w3.org/TR/xquery/#id-serialization-feature} + {Serialization Feature} and the + \l{http://www.w3.org/TR/xquery/#id-full-axis-feature} {Full Axis + Feature}. QtXmlPatterns currently passes 97% of the tests in the + \l{http://www.w3.org/XML/Query/test-suite} {XML Query Test Suite}. + Areas where conformance may be questionable and where behavior may + be changed in future releases include: + + \list + + \o Some corner cases involving namespaces and element constructors + are incorrect. + + \o XPath is a subset of XQuery and the implementation of + QtXmlPatterns uses XPath 2.0 with XQuery 1.0. + + \endlist + + The specifications discusses conformance further: + \l{http://www.w3.org/TR/xquery/}{XQuery 1.0: An XML Query + Language}. W3C's XQuery testing effort can be of interest as + well, \l{http://www.w3.org/XML/Query/test-suite/}{XML Query Test + Suite}. + + Currently \c fn:collection() does not access any data set, and + there is no API for providing data through the collection. As a + result, evaluating \c fn:collection() returns the empty + sequence. We intend to provide functionality for this in a future + release of Qt. + + Only queries encoded in UTF-8 are supported. + + \section2 XSLT 2.0 + + Partial support for XSLT was introduced in Qt 4.5. Future + releases of QtXmlPatterns will aim to support these XSLT + features: + + \list + \o Basic XSLT 2.0 processor + \o Serialization feature + \o Backwards Compatibility feature + \endlist + + For details, see \l{http://www.w3.org/TR/xslt20/#conformance}{XSL + Transformations (XSLT) Version 2.0, 21 Conformance}. + + \note In this release, XSLT support is considered experimental. + + Unsupported or partially supported XSLT features are documented + in the following table. The implementation of XSLT in Qt 4.5 can + be seen as XSLT 1.0 but with the data model of XPath 2.0 and + XSLT 2.0, and using the using the functionality of XPath 2.0 and + its accompanying function library. When QtXmlPatterns encounters + an unsupported or partially support feature, it will either report + a syntax error or silently continue, unless otherwise noted in the + table. + + The implementation currently passes 42% of W3C's XSLT test suite, + which focus on features introduced in XSLT 2.0. + + \table + \header + \o XSL Feature + \o Support Status + \row + \o \c xsl:key and \c fn:key() + \o not supported + \row + \o \c xsl:include + \o not supported + \row + \o \c xsl:import + \o not supported + \row + \o \c xsl:copy + + \o The \c copy-namespaces and \c inherit-namespaces attributes + have no effect. For copied comments, attributes and + processing instructions, the copy has the same node + identity as the original. + + \row + \o \c xsl:copy-of + \o The \c copy-namespaces attribute has no effect. + \row + \o \c fn:format-number() + \o not supported + \row + \o \c xsl:message + \o not supported + \row + \o \c xsl:use-when + \o not supported + \row + \o \c Tunnel Parameters + \o not supported + \row + \o \c xsl:attribute-set + \o not supported + \row + \o \c xsl:decimal-format + \o not supported + \row + \o \c xsl:fallback + \o not supported + \row + \o \c xsl:apply-imports + \o not supported + \row + \o \c xsl:character-map + \o not supported + \row + \o \c xsl:number + \o not supported + \row + \o \c xsl:namespace-alias + \o not supported + \row + \o \c xsl:output + \o not supported + \row + \o \c xsl:output-character + \o not supported + \row + \o \c xsl:preserve-space + \o not supported + \row + \o \c xsl:result-document + \o not supported + \row + \o Patterns + \o Complex patterns or patterns with predicates have issues. + \row + \o \c 2.0 Compatibility Mode + + \o Stylesheets are interpreted as XSLT 2.0 stylesheets, even + if the \c version attribute is in the XSLT source is + 1.0. In other words, the version attribute is ignored. + + \row + \o Grouping + + \o \c fn:current-group(), \c fn:grouping-key() and \c + xsl:for-each-group. + + \row + \o Regexp elements + \o \c xsl:analyze-string, \c xsl:matching-substring, + \c xsl:non-matching-substring, and \c fn:regex-group() + \row + \o Date & Time formatting + \o \c fn:format-dateTime(), \c fn:format-date() and fn:format-time(). + + \row + \o XPath Conformance + \o Since XPath is a subset of XSLT, its issues are in affect too. + \endtable + + The QtXmlPatterns implementation of the XPath Data Model does not + include entities (due to QXmlStreamReader not reporting them). + This means that functions \c unparsed-entity-uri() and \c + unparsed-entity-public-id() always return negatively. + + \section2 XPath 2.0 + + Since XPath 2.0 is a subset of XQuery 1.0, XPath 2.0 is + supported. Areas where conformance may be questionable and, + consequently, where behavior may be changed in future releases + include: + + \list + \o Regular expression support is currently not conformant + but follows Qt's QRegExp standard syntax. + + \o Operators for \c xs:time, \c xs:date, and \c xs:dateTime + are incomplete. + + \o Formatting of very large or very small \c xs:double, \c + xs:float, and \c xs:decimal values may be incorrect. + \endlist + + \section2 xml:id + + Processing of XML files supports \c xml:id. This allows elements + that have an attribute named \c xml:id to be looked up efficiently + with the \c fn:id() function. See + \l{http://www.w3.org/TR/xml-id/}{xml:id Version 1.0} for details. + + \section2 XML Schema 1.0 + + There are two ways QtXmlPatterns can be used to validate schemas: + You can use the C++ API in your Qt application using the classes + QXmlSchema and QXmlSchemaValidator, or you can use the command line + utility named xmlpatternsvalidator (located in the "bin" directory + of your Qt build). + + The QtXmlPatterns implementation of XML Schema validation supports + the schema specification version 1.0 in large parts. Known problems + of the implementation and areas where conformancy may be questionable + are: + + \list + \o Large \c minOccurs or \c maxOccurs values or deeply nested ones + require huge amount of memory which might cause the system to freeze. + Such a schema should be rewritten to use \c unbounded as value instead + of large numbers. This restriction will hopefully be fixed in a later release. + \o Comparison of really small or large floating point values might lead to + wrong results in some cases. However such numbers should not be relevant + for day-to-day usage. + \o Regular expression support is currently not conformant but follows + Qt's QRegExp standard syntax. + \o Identity constraint checks can not use the values of default or fixed + attribute definitions. + \endlist + + \section2 Resource Loading + + When QtXmlPatterns loads an XML resource, e.g., using the + \c fn:doc() function, the following schemes are supported: + + \table + \header + \o Scheme Name + \o Description + \row + \o \c file + \o Local files. + \row + \o \c data + + \o The bytes are encoded in the URI itself. e.g., \c + data:application/xml,%3Ce%2F%3E is \c <e/>. + + \row + \o \c ftp + \o Resources retrieved via FTP. + \row + \o \c http + \o Resources retrieved via HTTP. + \row + \o \c https + \o Resources retrieved via HTTPS. This will succeed if no SSL + errors are encountered. + \row + \o \c qrc + \o Qt Resource files. Expressing it as an empty scheme, :/..., + is not supported. + + \endtable + + \section2 XML + + XML 1.0 and XML Namespaces 1.0 are supported, as opposed to the + 1.1 versions. When a strings is passed to a query as a QString, + the characters must be XML 1.0 characters. Otherwise, the behavior + is undefined. This is not checked. + + URIs are first passed to QAbstractUriResolver. Check + QXmlQuery::setUriResolver() for possible rewrites. +*/ + +/*! + \namespace QPatternist + \brief The QPatternist namespace contains classes and functions required by the QtXmlPatterns module. + \internal +*/ diff --git a/doc/src/xml-processing/xml-processing.qdoc b/doc/src/xml-processing/xml-processing.qdoc new file mode 100644 index 0000000..63539c7 --- /dev/null +++ b/doc/src/xml-processing/xml-processing.qdoc @@ -0,0 +1,619 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group xml-tools + \title XML Classes + + \brief Classes that support XML, via, for example DOM and SAX. + + These classes are relevant to XML users. + + \generatelist{related} +*/ + +/*! + \page xml-processing.html + \title XML Processing + \ingroup technology-apis + + \brief An Overview of the XML processing facilities in Qt. + + In addition to core XML support, classes for higher level querying + and manipulation of XML data are provided by the QtXmlPatterns + module. In the QtSvg module, the QSvgRenderer and QSvgGenerator + classes can read and write a subset of SVG, an XML-based file + format. Qt also provides helper functions that may be useful to + those working with XML and XHTML: see Qt::escape() and + Qt::convertFromPlainText(). + + \section1 Topics: + + \list + \o \l {Classes for XML Processing} + \o \l {An Introduction to Namespaces} + \o \l {XML Streaming} + \o \l {The SAX Interface} + \o \l {Working with the DOM Tree} + \o \l {XQuery}{XQuery/XPath and XML Schema} + \list + \o \l{A Short Path to XQuery} + \endlist + \endlist + + \section1 Classes for XML Processing + + These classes are relevant to XML users. + + \annotatedlist xml-tools +*/ + +/*! + \page xml-namespaces.html + \title An Introduction to Namespaces + \target namespaces + + \contentspage XML Processing + \nextpage XML Streaming + + Parts of the Qt XML module documentation assume that you are familiar + with XML namespaces. Here we present a brief introduction; skip to + \link #namespacesConventions Qt XML documentation conventions \endlink + if you already know this material. + + Namespaces are a concept introduced into XML to allow a more modular + design. With their help data processing software can easily resolve + naming conflicts in XML documents. + + Consider the following example: + + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 6 + + Here we find three different uses of the name \e title. If you wish to + process this document you will encounter problems because each of the + \e titles should be displayed in a different manner -- even though + they have the same name. + + The solution would be to have some means of identifying the first + occurrence of \e title as the title of a book, i.e. to use the \e + title element of a book namespace to distinguish it from, for example, + the chapter title, e.g.: + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 7 + + \e book in this case is a \e prefix denoting the namespace. + + Before we can apply a namespace to element or attribute names we must + declare it. + + Namespaces are URIs like \e http://www.example.com/fnord/book/. This + does not mean that data must be available at this address; the URI is + simply used to provide a unique name. + + We declare namespaces in the same way as attributes; strictly speaking + they \e are attributes. To make for example \e + http://www.example.com/fnord/ the document's default XML namespace \e + xmlns we write + + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 8 + + To distinguish the \e http://www.example.com/fnord/book/ namespace from + the default, we must supply it with a prefix: + + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 9 + + A namespace that is declared like this can be applied to element and + attribute names by prepending the appropriate prefix and a ":" + delimiter. We have already seen this with the \e book:title element. + + Element names without a prefix belong to the default namespace. This + rule does not apply to attributes: an attribute without a prefix does + not belong to any of the declared XML namespaces at all. Attributes + always belong to the "traditional" namespace of the element in which + they appear. A "traditional" namespace is not an XML namespace, it + simply means that all attribute names belonging to one element must be + different. Later we will see how to assign an XML namespace to an + attribute. + + Due to the fact that attributes without prefixes are not in any XML + namespace there is no collision between the attribute \e title (that + belongs to the \e author element) and for example the \e title element + within a \e chapter. + + Let's clarify this with an example: + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 10 + + Within the \e document element we have two namespaces declared. The + default namespace \e http://www.example.com/fnord/ applies to the \e + book element, the \e chapter element, the appropriate \e title element + and of course to \e document itself. + + The \e book:author and \e book:title elements belong to the namespace + with the URI \e http://www.example.com/fnord/book/. + + The two \e book:author attributes \e title and \e name have no XML + namespace assigned. They are only members of the "traditional" + namespace of the element \e book:author, meaning that for example two + \e title attributes in \e book:author are forbidden. + + In the above example we circumvent the last rule by adding a \e title + attribute from the \e http://www.example.com/fnord/ namespace to \e + book:author: the \e fnord:title comes from the namespace with the + prefix \e fnord that is declared in the \e book:author element. + + Clearly the \e fnord namespace has the same namespace URI as the + default namespace. So why didn't we simply use the default namespace + we'd already declared? The answer is quite complex: + \list + \o attributes without a prefix don't belong to any XML namespace at + all, not even to the default namespace; + \o additionally omitting the prefix would lead to a \e title-title clash; + \o writing it as \e xmlns:title would declare a new namespace with the + prefix \e title instead of applying the default \e xmlns namespace. + \endlist + + With the Qt XML classes elements and attributes can be accessed in two + ways: either by refering to their qualified names consisting of the + namespace prefix and the "real" name (or \e local name) or by the + combination of local name and namespace URI. + + More information on XML namespaces can be found at + \l http://www.w3.org/TR/REC-xml-names/. + + \target namespacesConventions + \section1 Conventions Used in the Qt XML Documentation + + The following terms are used to distinguish the parts of names within + the context of namespaces: + \list + \o The \e {qualified name} + is the name as it appears in the document. (In the above example \e + book:title is a qualified name.) + \o A \e {namespace prefix} in a qualified name + is the part to the left of the ":". (\e book is the namespace prefix in + \e book:title.) + \o The \e {local part} of a name (also refered to as the \e {local + name}) appears to the right of the ":". (Thus \e title is the + local part of \e book:title.) + \o The \e {namespace URI} ("Uniform Resource Identifier") is a unique + identifier for a namespace. It looks like a URL + (e.g. \e http://www.example.com/fnord/ ) but does not require + data to be accessible by the given protocol at the named address. + \endlist + + Elements without a ":" (like \e chapter in the example) do not have a + namespace prefix. In this case the local part and the qualified name + are identical (i.e. \e chapter). + + \sa {DOM Bookmarks Example}, {SAX Bookmarks Example} +*/ + +/*! + \page xml-streaming.html + \title XML Streaming + + \previouspage An Introduction to Namespaces + \contentspage XML Processing + \nextpage The SAX Interface + + Since version 4.3, Qt provides two new classes for reading and + writing XML: QXmlStreamReader and QXmlStreamWriter. + + The QXmlStreamReader and QXmlStreamWriter are two new classes provided + in Qt 4.3 and later. A stream reader reports an XML document as a stream + of tokens. This differs from SAX as SAX applications provide handlers to + receive XML events from the parser whereas the QXmlStreamReader drives the + loop, pulling tokens from the reader when they are needed. + This pulling approach makes it possible to build recursive descent parsers, + allowing XML parsing code to be split into different methods or classes. + + QXmlStreamReader is a well-formed XML 1.0 parser that excludes external + parsed entities. Hence, data provided by the stream reader adheres to the + W3C's criteria for well-formed XML, as long as no error occurs. Otherwise, + functions such as \l{QXmlStreamReader::atEnd()}{atEnd()}, + \l{QXmlStreamReader::error()}{error()} and \l{QXmlStreamReader::hasError()} + {hasError()} can be used to check and view the errors. + + An example of QXmlStreamReader implementation would be the \c XbelReader in + \l{QXmlStream Bookmarks Example}, which is a subclass of QXmlStreamReader. + The constructor takes \a treeWidget as a parameter and the class has Xbel + specific functions: + + \snippet examples/xml/streambookmarks/xbelreader.h 1 + + \dots + \snippet examples/xml/streambookmarks/xbelreader.h 2 + \dots + + The \c read() function accepts a QIODevice and sets it with + \l{QXmlStreamReader::setDevice()}{setDevice()}. The + \l{QXmlStreamReader::raiseError()}{raiseError()} function is used to + display a custom error message, inidicating that the file's version + is incorrect. + + \snippet examples/xml/streambookmarks/xbelreader.cpp 1 + + The pendent to QXmlStreamReader is QXmlStreamWriter, which provides an XML + writer with a simple streaming API. QXmlStreamWriter operates on a + QIODevice and has specialised functions for all XML tokens or events you + want to write, such as \l{QXmlStreamWriter::writeDTD()}{writeDTD()}, + \l{QXmlStreamWriter::writeCharacters()}{writeCharacters()}, + \l{QXmlStreamWriter::writeComment()}{writeComment()} and so on. + + To write XML document with QXmlStreamWriter, you start a document with the + \l{QXmlStreamWriter::writeStartDocument()}{writeStartDocument()} function + and end it with \l{QXmlStreamWriter::writeEndDocument()} + {writeEndDocument()}, which implicitly closes all remaining open tags. + Element tags are opened with \l{QXmlStreamWriter::writeStartDocument()} + {writeStartDocument()} and followed by + \l{QXmlStreamWriter::writeAttribute()}{writeAttribute()} or + \l{QXmlStreamWriter::writeAttributes()}{writeAttributes()}, + element content, and then \l{QXmlStreamWriter::writeEndDocument()} + {writeEndDocument()}. Also, \l{QXmlStreamWriter::writeEmptyElement()} + {writeEmptyElement()} can be used to write empty elements. + + Element content comprises characters, entity references or nested elements. + Content can be written with \l{QXmlStreamWriter::writeCharacters()} + {writeCharacters()}, a function that also takes care of escaping all + forbidden characters and character sequences, + \l{QXmlStreamWriter::writeEntityReference()}{writeEntityReference()}, + or subsequent calls to \l{QXmlStreamWriter::writeStartElement()} + {writeStartElement()}. + + The \c XbelWriter class from \l{QXmlStream Bookmarks Example} is a subclass + of QXmlStreamWriter. Its \c writeFile() function illustrates the core + functions of QXmlStreamWriter mentioned above: + + \snippet examples/xml/streambookmarks/xbelwriter.cpp 1 +*/ + +/*! + \page xml-sax.html + \title The SAX interface + + \previouspage XML Streaming + \contentspage XML Processing + \nextpage Working with the DOM Tree + + SAX is an event-based standard interface for XML parsers. + The Qt interface follows the design of the SAX2 Java implementation. + Its naming scheme was adapted to fit the Qt naming conventions. + Details on SAX2 can be found at \l{http://www.saxproject.org}. + + Support for SAX2 filters and the reader factory are under + development. The Qt implementation does not include the SAX1 + compatibility classes present in the Java interface. + + \section1 Introduction to SAX2 + + The SAX2 interface is an event-driven mechanism to provide the user with + document information. An "event" in this context means something + reported by the parser, for example, it has encountered a start tag, + or an end tag, etc. + + To make it less abstract consider the following example: + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 3 + + Whilst reading (a SAX2 parser is usually referred to as "reader") + the above document three events would be triggered: + \list 1 + \o A start tag occurs (\c{<quote>}). + \o Character data (i.e. text) is found, "A quotation.". + \o An end tag is parsed (\c{</quote>}). + \endlist + + Each time such an event occurs the parser reports it; you can set up + event handlers to respond to these events. + + Whilst this is a fast and simple approach to read XML documents, + manipulation is difficult because data is not stored, simply handled + and discarded serially. The \l{Working with the DOM Tree}{DOM interface} + reads in and stores the whole document in a tree structure; + this takes more memory, but makes it easier to manipulate the + document's structure. + + The Qt XML module provides an abstract class, \l QXmlReader, that + defines the interface for potential SAX2 readers. Qt includes a reader + implementation, \l QXmlSimpleReader, that is easy to adapt through + subclassing. + + The reader reports parsing events through special handler classes: + \table + \header \o Handler class \o Description + \row \o \l QXmlContentHandler + \o Reports events related to the content of a document (e.g. the start tag + or characters). + \row \o \l QXmlDTDHandler + \o Reports events related to the DTD (e.g. notation declarations). + \row \o \l QXmlErrorHandler + \o Reports errors or warnings that occurred during parsing. + \row \o \l QXmlEntityResolver + \o Reports external entities during parsing and allows users to resolve + external entities themselves instead of leaving it to the reader. + \row \o \l QXmlDeclHandler + \o Reports further DTD related events (e.g. attribute declarations). + \row \o \l QXmlLexicalHandler + \o Reports events related to the lexical structure of the + document (the beginning of the DTD, comments etc.). + \endtable + + These classes are abstract classes describing the interface. The \l + QXmlDefaultHandler class provides a "do nothing" default + implementation for all of them. Therefore users only need to overload + the QXmlDefaultHandler functions they are interested in. + + To read input XML data a special class \l QXmlInputSource is used. + + Apart from those already mentioned, the following SAX2 support classes + provide additional useful functionality: + \table + \header \o Class \o Description + \row \o \l QXmlAttributes + \o Used to pass attributes in a start element event. + \row \o \l QXmlLocator + \o Used to obtain the actual parsing position of an event. + \row \o \l QXmlNamespaceSupport + \o Used to implement namespace support for a reader. Note that + namespaces do not change the parsing behavior. They are only + reported through the handler. + \endtable + + The \l{SAX Bookmarks example} illustrates how to subclass + QXmlDefaultHandler to read an XML bookmark file (XBEL) and + how to generate XML by hand. + + \section1 SAX2 Features + + The behavior of an XML reader depends on its support for certain + optional features. For example, a reader may have the feature "report + attributes used for namespace declarations and prefixes along with + the local name of a tag". Like every other feature this has a unique + name represented by a URI: it is called + \e http://xml.org/sax/features/namespace-prefixes. + + The Qt SAX2 implementation can report whether the reader has + particular functionality using the QXmlReader::hasFeature() + function. Available features can be tested with QXmlReader::feature(), + and switched on or off using QXmlReader::setFeature(). + + Consider the example + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 4 + A reader that does not support the \e + http://xml.org/sax/features/namespace-prefixes feature would report + the element name \e document but not its attributes \e xmlns:book and + \e xmlns with their values. A reader with the feature \e + http://xml.org/sax/features/namespace-prefixes reports the namespace + attributes if the \link QXmlReader::feature() feature\endlink is + switched on. + + Other features include \e http://xml.org/sax/features/namespace + (namespace processing, implies \e + http://xml.org/sax/features/namespace-prefixes) and \e + http://xml.org/sax/features/validation (the ability to report + validation errors). + + Whilst SAX2 leaves it to the user to define and implement whatever + features are required, support for \e + http://xml.org/sax/features/namespace (and thus \e + http://xml.org/sax/features/namespace-prefixes) is mandantory. + The \l QXmlSimpleReader implementation of \l QXmlReader, + supports them, and can do namespace processing. + + \l QXmlSimpleReader is not validating, so it + does not support \e http://xml.org/sax/features/validation. + + \section1 Namespace Support via Features + + As we have seen in the previous section, we can configure the + behavior of the reader when it comes to namespace + processing. This is done by setting and unsetting the + \e http://xml.org/sax/features/namespaces and + \e http://xml.org/sax/features/namespace-prefixes features. + + They influence the reporting behavior in the following way: + \list 1 + \o Namespace prefixes and local parts of elements and attributes can + be reported. + \o The qualified names of elements and attributes are reported. + \o \l QXmlContentHandler::startPrefixMapping() and \l + QXmlContentHandler::endPrefixMapping() are called by the reader. + \o Attributes that declare namespaces (i.e. the attribute \e xmlns and + attributes starting with \e{xmlns:}) are reported. + \endlist + + Consider the following element: + \snippet doc/src/snippets/code/doc_src_qtxml.qdoc 5 + With \e http://xml.org/sax/features/namespace-prefixes set to true + the reader will report four attributes; but with the \e + namespace-prefixes feature set to false only three, with the \e + xmlns:fnord attribute defining a namespace being "invisible" to the + reader. + + The \e http://xml.org/sax/features/namespaces feature is responsible + for reporting local names, namespace prefixes and URIs. With \e + http://xml.org/sax/features/namespaces set to true the parser will + report \e title as the local name of the \e fnord:title attribute, \e + fnord being the namespace prefix and \e http://example.com/fnord/ as + the namespace URI. When \e http://xml.org/sax/features/namespaces is + false none of them are reported. + + In the current implementation the Qt XML classes follow the definition + that the prefix \e xmlns itself isn't associated with any namespace at all + (see \link http://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-using + http://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-using \endlink). + Therefore even with \e http://xml.org/sax/features/namespaces and + \e http://xml.org/sax/features/namespace-prefixes both set to true + the reader won't return either a local name, a namespace prefix or + a namespace URI for \e xmlns:fnord. + + This might be changed in the future following the W3C suggestion + \link http://www.w3.org/2000/xmlns/ http://www.w3.org/2000/xmlns/ \endlink + to associate \e xmlns with the namespace \e http://www.w3.org/2000/xmlns. + + As the SAX2 standard suggests, \l QXmlSimpleReader defaults to having + \e http://xml.org/sax/features/namespaces set to true and + \e http://xml.org/sax/features/namespace-prefixes set to false. + When changing this behavior using \l QXmlSimpleReader::setFeature() + note that the combination of both features set to + false is illegal. + + \section2 Summary + + \l QXmlSimpleReader implements the following behavior: + + \table + \header \o (namespaces, namespace-prefixes) + \o Namespace prefix and local part + \o Qualified names + \o Prefix mapping + \o xmlns attributes + \row \o (true, false) \o Yes \o Yes* \o Yes \o No + \row \o (true, true) \o Yes \o Yes \o Yes \o Yes + \row \o (false, true) \o No* \o Yes \o No* \o Yes + \row \o (false, false) \i41 Illegal + \endtable + + The behavior of the entries marked with an asterisk (*) is not specified by SAX. + + \section1 Properties + + Properties are a more general concept. They have a unique name, + represented as an URI, but their value is \c void*. Thus nearly + anything can be used as a property value. This concept involves some + danger, though: there is no means of ensuring type-safety; the user + must take care that they pass the right type. Properties are + useful if a reader supports special handler classes. + + The URIs used for features and properties often look like URLs, e.g. + \c http://xml.org/sax/features/namespace. This does not mean that the + data required is at this address. It is simply a way of defining + unique names. + + Anyone can define and use new SAX2 properties for their readers. + Property support is not mandatory. + + To set or query properties the following functions are provided: \l + QXmlReader::setProperty(), \l QXmlReader::property() and \l + QXmlReader::hasProperty(). +*/ + +/*! + \page xml-dom.tml + \title Working with the DOM Tree + \target dom + + \previouspage The SAX Interface + \contentspage XML Processing + \nextpage {XQuery}{XQuery/XPath and XML Schema} + + DOM Level 2 is a W3C Recommendation for XML interfaces that maps the + constituents of an XML document to a tree structure. The specification + of DOM Level 2 can be found at \l{http://www.w3.org/DOM/}. + + \target domIntro + \section1 Introduction to DOM + + DOM provides an interface to access and change the content and + structure of an XML file. It makes a hierarchical view of the document + (a tree view). Thus -- in contrast to the SAX2 interface -- an object + model of the document is resident in memory after parsing which makes + manipulation easy. + + All DOM nodes in the document tree are subclasses of \l QDomNode. The + document itself is represented as a \l QDomDocument object. + + Here are the available node classes and their potential child classes: + + \list + \o \l QDomDocument: Possible children are + \list + \o \l QDomElement (at most one) + \o \l QDomProcessingInstruction + \o \l QDomComment + \o \l QDomDocumentType + \endlist + \o \l QDomDocumentFragment: Possible children are + \list + \o \l QDomElement + \o \l QDomProcessingInstruction + \o \l QDomComment + \o \l QDomText + \o \l QDomCDATASection + \o \l QDomEntityReference + \endlist + \o \l QDomDocumentType: No children + \o \l QDomEntityReference: Possible children are + \list + \o \l QDomElement + \o \l QDomProcessingInstruction + \o \l QDomComment + \o \l QDomText + \o \l QDomCDATASection + \o \l QDomEntityReference + \endlist + \o \l QDomElement: Possible children are + \list + \o \l QDomElement + \o \l QDomText + \o \l QDomComment + \o \l QDomProcessingInstruction + \o \l QDomCDATASection + \o \l QDomEntityReference + \endlist + \o \l QDomAttr: Possible children are + \list + \o \l QDomText + \o \l QDomEntityReference + \endlist + \o \l QDomProcessingInstruction: No children + \o \l QDomComment: No children + \o \l QDomText: No children + \o \l QDomCDATASection: No children + \o \l QDomEntity: Possible children are + \list + \o \l QDomElement + \o \l QDomProcessingInstruction + \o \l QDomComment + \o \l QDomText + \o \l QDomCDATASection + \o \l QDomEntityReference + \endlist + \o \l QDomNotation: No children + \endlist + + With \l QDomNodeList and \l QDomNamedNodeMap two collection classes + are provided: \l QDomNodeList is a list of nodes, + and \l QDomNamedNodeMap is used to handle unordered sets of nodes + (often used for attributes). + + The \l QDomImplementation class allows the user to query features of the + DOM implementation. + + To get started please refer to the \l QDomDocument documentation. + You might also want to take a look at the \l{DOM Bookmarks example}, + which illustrates how to read and write an XML bookmark file (XBEL) + using DOM. +*/ diff --git a/doc/src/xml-processing/xquery-introduction.qdoc b/doc/src/xml-processing/xquery-introduction.qdoc new file mode 100644 index 0000000..76d99dc --- /dev/null +++ b/doc/src/xml-processing/xquery-introduction.qdoc @@ -0,0 +1,1006 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Free Documentation License +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page xquery-introduction.html +\title A Short Path to XQuery + +\pagekeywords XPath XQuery +\startpage XQuery +\target XQuery-introduction + +XQuery is a language for querying XML data or non-XML data that can be +modeled as XML. XQuery is specified by the \l{http://www.w3.org}{W3C}. + +\tableofcontents + +\section1 Introduction + +Where Java and C++ are \e{statement-based} languages, the XQuery +language is \e{expression-based}. The simplest XQuery expression is an +XML element constructor: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 20 + +This \c{<recipe/>} element is an XQuery expression that forms a +complete XQuery. In fact, this XQuery doesn't actually query +anything. It just creates an empty \c{<recipe/>} element in the +output. But \l{Constructing Elements} {constructing new elements in an +XQuery} is often necessary. + +An XQuery expression can also be enclosed in curly braces and embedded +in another XQuery expression. This XQuery has a document expression +embedded in a node expression: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 21 + +It creates a new \c{<html>} element in the output and sets its \c{id} +attribute to be the \c{id} attribute from an \c{<html>} element in the +\c{other.html} file. + +\section1 Using Path Expressions To Match And Select Items + +In C++ and Java, we write nested \c{for} loops and recursive functions +to traverse XML trees in search of elements of interest. In XQuery, we +write these iterative and recursive algorithms with \e{path +expressions}. + +A path expression looks somewhat like a typical \e{file pathname} for +locating a file in a hierarchical file system. It is a sequence of one +or more \e{steps} separated by slash '/' or double slash '//'. +Although path expressions are used for traversing XML trees, not file +systems, in QtXmlPatterms we can model a file system to look like an +XML tree, so in QtXmlPatterns we can use XQuery to traverse a file +system. See the \l {File System Example} {file system example}. + +Think of a path expression as an algorithm for traversing an XML tree +to find and collect items of interest. This algorithm is evaluated by +evaluating each step moving from left to right through the sequence. A +step is evaluated with a set of input items (nodes and atomic values), +sometimes called the \e focus. The step is evaluated for each item in +the focus. These evaluations produce a new set of items, called the \e +result, which then becomes the focus that is passed to the next step. +Evaluation of the final step produces the final result, which is the +result of the XQuery. The items in the result set are presented in +\l{http://www.w3.org/TR/xquery/#id-document-order} {document order} +and without duplicates. + +With QtXmlPatterns, a standard way to present the initial focus to a +query is to call QXmlQuery::setFocus(). Another common way is to let +the XQuery itself create the initial focus by using the first step of +the path expression to call the XQuery \c{doc()} function. The +\c{doc()} function loads an XML document and returns the \e {document +node}. Note that the document node is \e{not} the same as the +\e{document element}. The \e{document node} is a node constructed in +memory, when the document is loaded. It represents the entire XML +document, not the document element. The \e{document element} is the +single, top-level XML element in the file. The \c{doc()} function +returns the document node, which becomes the singleton node in the +initial focus set. The document node will have one child node, and +that child node will represent the document element. Consider the +following XQuery: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 18 + +The \c{doc()} function loads the \c{cookbook.xml} file and returns the +document node. The document node then becomes the focus for the next +step \c{//recipe}. Here the double slash means select all \c{<recipe>} +elements found below the document node, regardless of where they +appear in the document tree. The query selects all \c{<recipe>} +elements in the cookbook. See \l{Running The Cookbook Examples} for +instructions on how to run this query (and most of the ones that +follow) from the command line. + +Conceptually, evaluation of the steps of a path expression is similar +to iterating through the same number of nested \e{for} loops. Consider +the following XQuery, which builds on the previous one: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 19 + +This XQuery is a single path expression composed of three steps. The +first step creates the initial focus by calling the \c{doc()} +function. We can paraphrase what the query engine does at each step: + +\list 1 + \o for each node in the initial focus (the document node)... + \o for each descendant node that is a \c{<recipe>} element... + \o collect the child nodes that are \c{<title>} elements. +\endlist + +Again the double slash means select all the \c{<recipe>} elements in the +document. The single slash before the \c{<title>} element means select +only those \c{<title>} elements that are \e{child} elements of a +\c{<recipe>} element (i.e. not grandchildren, etc). The XQuery evaluates +to a final result set containing the \c{<title>} element of each +\c{<recipe>} element in the cookbook. + +\section2 Axis Steps + +The most common kind of path step is called an \e{axis step}, which +tells the query engine which way to navigate from the context node, +and which test to perform when it encounters nodes along the way. An +axis step has two parts, an \e{axis specifier}, and a \e{node test}. +Conceptually, evaluation of an axis step proceeds as follows: For each +node in the focus set, the query engine navigates out from the node +along the specified axis and applies the node test to each node it +encounters. The nodes selected by the node test are collected in the +result set, which becomes the focus set for the next step. + +In the example XQuery above, the second and third steps are both axis +steps. Both apply the \c{element(name)} node test to nodes encountered +while traversing along some axis. But in this example, the two axis +steps are written in a \l{Shorthand Form} {shorthand form}, where the +axis specifier and the node test are not written explicitly but are +implied. XQueries are normally written in this shorthand form, but +they can also be written in the longhand form. If we rewrite the +XQuery in the longhand form, it looks like this: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 22 + +The two axis steps have been expanded. The first step (\c{//recipe}) +has been rewritten as \c{/descendant-or-self::element(recipe)}, where +\c{descendant-or-self::} is the axis specifier and \c{element(recipe)} +is the node test. The second step (\c{title}) has been rewritten as +\c{/child::element(title)}, where \c{child::} is the axis specifier +and \c{element(title)} is the node test. The output of the expanded +XQuery will be exactly the same as the output of the shorthand form. + +To create an axis step, concatenate an axis specifier and a node +test. The following sections list the axis specifiers and node tests +that are available. + +\section2 Axis Specifiers + +An axis specifier defines the direction you want the query engine to +take, when it navigates away from the context node. QtXmlPatterns +supports the following axes. + +\table +\header + \o Axis Specifier + \o refers to the axis containing... + \row + \o \c{self::} + \o the context node itself + \row + \o \c{attribute::} + \o all attribute nodes of the context node + \row + \o \c{child::} + \o all child nodes of the context node (not attributes) + \row + \o \c{descendant::} + \o all descendants of the context node (children, grandchildren, etc) + \row + \o \c{descendant-or-self::} + \o all nodes in \c{descendant} + \c{self} + \row + \o \c{parent::} + \o the parent node of the context node, or empty if there is no parent + \row + \o \c{ancestor::} + \o all ancestors of the context node (parent, grandparent, etc) + \row + \o \c{ancestor-or-self::} + \o all nodes in \c{ancestor} + \c{self} + \row + \o \c{following::} + \o all nodes in the tree containing the context node, \e not + including \c{descendant}, \e and that follow the context node + in the document + \row + \o \c{preceding::} + \o all nodes in the tree contianing the context node, \e not + including \c{ancestor}, \e and that precede the context node in + the document + \row + \o \c{following-sibling::} + \o all children of the context node's \c{parent} that follow the + context node in the document + \row + \o \c{preceding-sibling::} + \o all children of the context node's \c{parent} that precede the + context node in the document +\endtable + +\section2 Node Tests + +A node test is a conditional expression that must be true for a node +if the node is to be selected by the axis step. The conditional +expression can test just the \e kind of node, or it can test the \e +kind of node and the \e name of the node. The XQuery specification for +\l{http://www.w3.org/TR/xquery/#node-tests} {node tests} also defines +a third condition, the node's \e {Schema Type}, but schema type tests +are not supported in QtXmlPatterns. + +QtXmlPatterns supports the following node tests. The tests that have a +\c{name} parameter test the node's name in addition to its \e{kind} +and are often called the \l{Name Tests}. + +\table +\header + \o Node Test + \o matches all... + \row + \o \c{node()} + \o nodes of any kind + \row + \o \c{text()} + \o text nodes + \row + \o \c{comment()} + \o comment nodes + \row + \o \c{element()} + \o element nodes (same as star: *) + \row + \o \c{element(name)} + \o element nodes named \c{name} + \row + \o \c{attribute()} + \o attribute nodes + \row + \o \c{attribute(name)} + \o attribute nodes named \c{name} + \row + \o \c{processing-instruction()} + \o processing-instructions + \row + \o \c{processing-instruction(name)} + \o processing-instructions named \c{name} + \row + \o \c{document-node()} + \o document nodes (there is only one) + \row + \o \c{document-node(element(name))} + \o document node with document element \c{name} +\endtable + +\target Shorthand Form +\section2 Shorthand Form + +Writing axis steps using the longhand form with axis specifiers and +node tests is semantically clear but syntactically verbose. The +shorthand form is easy to learn and, once you learn it, just as easy +to read. In the shorthand form, the axis specifier and node test are +implied by the syntax. XQueries are normally written in the shorthand +form. Here is a table of some frequently used shorthand forms: + +\table +\header + \o Shorthand syntax + \o Short for... + \o matches all... + \row + \o \c{name} + \o \c{child::element(name)} + \o child nodes that are \c{name} elements + + \row + \o \c{*} + \o \c{child::element()} + \o child nodes that are elements (\c{node()} matches + \e all child nodes) + + \row + \o \c{..} + \o \c{parent::node()} + \o parent nodes (there is only one) + + \row + \o \c{@*} + \o \c{attribute::attribute()} + \o attribute nodes + + \row + \o \c{@name} + \o \c{attribute::attribute(name)} + \o \c{name} attributes + + \row + \o \c{//} + \o \c{descendant-or-self::node()} + \o descendent nodes (when used instead of '/') + +\endtable + +The \l{http://www.w3.org/TR/xquery/}{XQuery language specification} +has a more detailed section on the shorthand form, which it calls the +\l{http://www.w3.org/TR/xquery/#abbrev} {abbreviated syntax}. More +examples of path expressions written in the shorthand form are found +there. There is also a section listing examples of path expressions +written in the \l{http://www.w3.org/TR/xquery/#unabbrev} {longhand +form}. + +\target Name Tests +\section2 Name Tests + +The name tests are the \l{Node Tests} that have the \c{name} +parameter. A name test must match the node \e name in addition to the +node \e kind. We have already seen name tests used: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 19 + +In this path expression, both \c{recipe} and \c{title} are name tests +written in the shorthand form. XQuery resolves these names +(\l{http://www.w3.org/TR/xquery/#id-basics}{QNames}) to their expanded +form using whatever +\l{http://www.w3.org/TR/xquery/#dt-namespace-declaration} {namespace +declarations} it knows about. Resolving a name to its expanded form +means replacing its namespace prefix, if one is present (there aren't +any present in the example), with a namespace URI. The expanded name +then consists of the namespace URI and the local name. + +But the names in the example above don't have namespace prefixes, +because we didn't include a namespace declaration in our +\c{cookbook.xml} file. However, we will often use XQuery to query XML +documents that use namespaces. Forgetting to declare the correct +namespace(s) in an XQuery is a common cause of XQuery failures. Let's +add a \e{default} namespace to \c{cookbook.xml} now. Change the +\e{document element} in \c{cookbook.xml} from: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 23 + +to... + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 24 + +This is called a \e{default namespace} declaration because it doesn't +include a namespace prefix. By including this default namespace +declaration in the document element, we mean that all unprefixed +\e{element} names in the document, including the document element +itself (\c{cookbook}), are automatically in the default namespace +\c{http://cookbook/namespace}. Note that unprefixed \e{attribute} +names are not affected by the default namespace declaration. They are +always considered to be in \e{no namespace}. Note also that the URL +we choose as our namespace URI need not refer to an actual location, +and doesn't refer to one in this case. But click on +\l{http://www.w3.org/XML/1998/namespace}, for example, which is the +namespace URI for elements and attributes prefixed with \c{xml:}. + +Now when we try to run the previous XQuery example, no output is +produced! The path expression no longer matches anything in the +cookbook file because our XQuery doesn't yet know about the namespace +declaration we added to the cookbook document. There are two ways we +can declare the namespace in the XQuery. We can give it a \e{namespace +prefix} (e.g. \c{c} for cookbook) and prefix each name test with the +namespace prefix: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 3 + +Or we can declare the namespace to be the \e{default element +namespace}, and then we can still run the original XQuery: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 4 + +Both methods will work and produce the same output, all the +\c{<title>} elements: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 5 + +But note how the output is slightly different from the output we saw +before we added the default namespace declaration to the cookbook file. +QtXmlPatterns automatically includes the correct namespace attribute +in each \c{<title>} element in the output. When QtXmlPatterns loads a +document and expands a QName, it creates an instance of QXmlName, +which retains the namespace prefix along with the namespace URI and +the local name. See QXmlName for further details. + +One thing to keep in mind from this namespace discussion, whether you +run XQueries in a Qt program using QtXmlPatterns, or you run them from +the command line using xmlpatterns, is that if you don't get the +output you expect, it might be because the data you are querying uses +namespaces, but you didn't declare those namespaces in your XQuery. + +\section3 Wildcards in Name Tests + +The wildcard \c{'*'} can be used in a name test. To find all the +attributes in the cookbook but select only the ones in the \c{xml} +namespace, use the \c{xml:} namespace prefix but replace the +\e{local name} (the attribute name) with the wildcard: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 7 + +Oops! If you save this XQuery in \c{file.xq} and run it through +\c{xmlpatterns}, it doesn't work. You get an error message instead, +something like this: \e{Error SENR0001 in file:///...file.xq, at line +1, column 1: Attribute xml:id can't be serialized because it appears +at the top level.} The XQuery actually ran correctly. It selected a +bunch of \c{xml:id} attributes and put them in the result set. But +then \c{xmlpatterns} sent the result set to a \l{QXmlSerializer} +{serializer}, which tried to output it as well-formed XML. Since the +result set contains only attributes and attributes alone are not +well-formed XML, the \l{QXmlSerializer} {serializer} reports a +\l{http://www.w3.org/TR/2005/WD-xslt-xquery-serialization-20050915/#id-errors} +{serialization error}. + +Fear not. XQuery can do more than just find and select elements and +attributes. It can \l{Constructing Elements} {construct new ones on +the fly} as well, which is what we need to do here if we want +\c{xmlpatterns} to let us see the attributes we selected. The example +above and the ones below are revisited in the \l{Constructing +Elements} section. You can jump ahead to see the modified examples +now, and then come back, or you can press on from here. + +To find all the \c{name} attributes in the cookbook and select them +all regardless of their namespace, replace the namespace prefix with +the wildcard and write \c{name} (the attribute name) as the local +name: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 8 + +To find and select all the attributes of the \e{document element} in +the cookbook, replace the entire name test with the wildcard: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 9 + +\section1 Using Predicates In Path Expressions + +Predicates can be used to further filter the nodes selected by a path +expression. A predicate is an expression in square brackets ('[' and +']') that either returns a boolean value or a number. A predicate can +appear at the end of any path step in a path expression. The predicate +is applied to each node in the focus set. If a node passes the +filter, the node is included in the result set. The query below +selects the recipe element that has the \c{<title>} element +\c{"Hard-Boiled Eggs"}. + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 10 + +The dot expression ('.') can be used in predicates and path +expressions to refer to the current context node. The following query +uses the dot expression to refer to the current \c{<method>} element. +The query selects the empty \c{<method>} elements from the cookbook. + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 11 + +Note that passing the dot expression to the +\l{http://www.w3.org/TR/xpath-functions/#func-string-length} +{string-length()} function is optional. When +\l{http://www.w3.org/TR/xpath-functions/#func-string-length} +{string-length()} is called with no parameter, the context node is +assumed: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 12 + +Actually, selecting an empty \c{<method>} element might not be very +useful by itself. It doesn't tell you which recipe has the empty +method: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 31 + +\target Empty Method Not Robust +What you probably want to see instead are the \c{<recipe>} elements that +have empty \c{<method>} elements: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 32 + +The predicate uses the +\l{http://www.w3.org/TR/xpath-functions/#func-string-length} +{string-length()} function to test the length of each \c{<method>} +element in each \c{<recipe>} element found by the node test. If a +\c{<method>} contains no text, the predicate evaluates to \c{true} and +the \c{<recipe>} element is selected. If the method contains some +text, the predicate evaluates to \c{false}, and the \c{<recipe>} +element is discarded. The output is the entire recipe that has no +instructions for preparation: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 33 + +The astute reader will have noticed that this use of +\c{string-length()} to find an empty element is unreliable. It works +in this case, because the method element is written as \c{<method/>}, +guaranteeing that its string length will be 0. It will still work if +the method element is written as \c{<method></method>}, but it will +fail if there is any whitespace between the opening and ending +\c{<method>} tags. A more robust way to find the recipes with empty +methods is presented in the section on \l{Boolean Predicates}. + +There are many more functions and operators defined for XQuery and +XPath. They are all \l{http://www.w3.org/TR/xpath-functions} +{documented in the specification}. + +\section2 Positional Predicates + +Predicates are often used to filter items based on their position in +a sequence. For path expressions processing items loaded from XML +documents, the normal sequence is +\l{http://www.w3.org/TR/xquery/#id-document-order} {document order}. +This query returns the second \c{<recipe>} element in the +\c{cookbook.xml} file: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 13 + +The other frequently used positional function is +\l{http://www.w3.org/TR/xpath-functions/#func-last} {last()}, which +returns the numeric position of the last item in the focus set. Stated +another way, \l{http://www.w3.org/TR/xpath-functions/#func-last} +{last()} returns the size of the focus set. This query returns the +last recipe in the cookbook: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 16 + +And this query returns the next to last \c{<recipe>}: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 17 + +\section2 Boolean Predicates + +The other kind of predicate evaluates to \e true or \e false. A +boolean predicate takes the value of its expression and determines its +\e{effective boolean value} according to the following rules: + +\list + \o An expression that evaluates to a single node is \c{true}. + + \o An expression that evaluates to a string is \c{false} if the + string is empty and \c{true} if the string is not empty. + + \o An expression that evaluates to a boolean value (i.e. type + \c{xs:boolean}) is that value. + + \o If the expression evaluates to anything else, it's an error + (e.g. type \c{xs:date}). + +\endlist + +We have already seen some boolean predicates in use. Earlier, we saw +a \e{not so robust} way to find the \l{Empty Method Not Robust} +{recipes that have no instructions}. \c{[string-length(method) = 0]} +is a boolean predicate that would fail in the example if the empty +method element was written with both opening and closing tags and +there was whitespace between the tags. Here is a more robust way that +uses a different boolean predicate. + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 34 + +This one uses the +\l{http://www.w3.org/TR/xpath-functions/#func-empty} {empty()} and +function to test whether the method contains any steps. If the method +contains no steps, then \c{empty(step)} will return \c{true}, and +hence the predicate will evaluate to \c{true}. + +But even that version isn't foolproof. Suppose the method does contain +steps, but all the steps themselves are empty. That's still a case of +a recipe with no instructions that won't be detected. There is a +better way: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 35 + +This version uses the +\l{http://www.w3.org/TR/xpath-functions/#func-not} {not} and +\l{http://www.w3.org/TR/xpath-functions/#func-normalize-space} +{normalize-space()} functions. \c{normalize-space(method))} returns +the contents of the method element as a string, but with all the +whitespace normalized, i.e., the string value of each \c{<step>} +element will have its whitespace normalized, and then all the +normalized step values will be concatenated. If that string is empty, +then \c{not()} returns \c{true} and the predicate is \c{true}. + +We can also use the +\l{http://www.w3.org/TR/xpath-functions/#func-position} {position()} +function in a comparison to inspect positions with conditional logic. The +\l{http://www.w3.org/TR/xpath-functions/#func-position} {position()} +function returns the position index of the current context item in the +sequence of items: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 14 + +Note that the first position in the sequence is position 1, not 0. We +can also select \e{all} the recipes after the first one: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 15 + +\target Constructing Elements +\section1 Constructing Elements + +In the section about \l{Wildcards in Name Tests} {using wildcards in +name tests}, we saw three simple example XQueries, each of which +selected a different list of XML attributes from the cookbook. We +couldn't use \c{xmlpatterns} to run these queries, however, because +\c{xmlpatterns} sends the XQuery results to a \l{QXmlSerializer} +{serializer}, which expects to serialize the results as well-formed +XML. Since a list of XML attributes by itself is not well-formed XML, +the serializer reported an error for each XQuery. + +Since an attribute must appear in an element, for each attribute in +the result set, we must create an XML element. We can do that using a +\l{http://www.w3.org/TR/xquery/#id-for-let} {\e{for} clause} with a +\l{http://www.w3.org/TR/xquery/#id-variables} {bound variable}, and a +\l{http://www.w3.org/TR/xquery/#id-orderby-return} {\e{return} +clause} with an element constructor: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 25 + +The \e{for} clause produces a sequence of attribute nodes from the result +of the path expression. Each attribute node in the sequence is bound +to the variable \c{$i}. The \e{return} clause then constructs a \c{<p>} +element around the attribute node. Here is the output: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 28 + +The output contains one \c{<p>} element for each \c{xml:id} attribute +in the cookbook. Note that XQuery puts each attribute in the right +place in its \c{<p>} element, despite the fact that in the \e{return} +clause, the \c{$i} variable is positioned as if it is meant to become +\c{<p>} element content. + +The other two examples from the \l{Wildcards in Name Tests} {wildcard} +section can be rewritten the same way. Here is the XQuery that selects +all the \c{name} attributes, regardless of namespace: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 26 + +And here is its output: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 29 + +And here is the XQuery that selects all the attributes from the +\e{document element}: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 27 + +And here is its output: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 30 + +\section2 Element Constructors are Expressions + +Because node constructors are expressions, they can be used in +XQueries wherever expressions are allowed. + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 40 + +If \c{cookbook.xml} is loaded without error, a \c{<oppskrift>} element +(Norwegian word for recipe) is constructed for each \c{<recipe>} +element in the cookbook, and the child nodes of the \c{<recipe>} are +copied into the \c{<oppskrift>} element. But if the cookbook document +doesn't exist or does not contain well-formed XML, a single +\c{<oppskrift>} element is constructed containing an error message. + +\section1 Constructing Atomic Values + +XQuery also has atomic values. An atomic value is a value in the value +space of one of the built-in datatypes in the \l +{http://www.w3.org/TR/xmlschema-2} {XML Schema language}. These +\e{atomic types} have built-in operators for doing arithmetic, +comparisons, and for converting values to other atomic types. See the +\l {http://www.w3.org/TR/xmlschema-2/#built-in-datatypes} {Built-in +Datatype Hierarchy} for the entire tree of built-in, primitive and +derived atomic types. \note Click on a data type in the tree for its +detailed specification. + +To construct an atomic value as element content, enclose an expression +in curly braces and embed it in the element constructor: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 36 + +Sending this XQuery through xmlpatterns produces: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 37 + +To compute the value of an attribute, enclose the expression in +curly braces and embed it in the attribute value: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 38 + +Sending this XQuery through xmlpatterns produces: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 39 + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 40 + +If \c{cookbook.xml} is loaded without error, a \c{<oppskrift>} element +(Norweigian word for recipe) is constructed for each \c{<recipe>} +element in the cookbook, and the child nodes of the \c{<recipe>} are +copied into the \c{<oppskrift>} element. But if the cookbook document +doesn't exist or does not contain well-formed XML, a single +\c{<oppskrift>} element is constructed containing an error message. + +\section1 Running The Cookbook Examples + +Most of the XQuery examples in this document refer to the +\c{cookbook.xml} example file from the \l{Recipes Example}. +Copy the \c{cookbook.xml} to your current directory, save one of the +cookbook XQuery examples in a \c{.xq} file (e.g., \c{file.xq}), and +run the XQuery using Qt's command line utility: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 6 + +\section1 Further Reading + +There is much more to the XQuery language than we have presented in +this short introduction. We will be adding more here in later +releases. In the meantime, playing with the \c{xmlpatterns} utility +and making modifications to the XQuery examples provided here will be +quite informative. An XQuery textbook will be a good investment. + +You can also ask questions on XQuery mail lists: + +\list +\o +\l{http://qt.nokia.com/lists/qt-interest/}{qt-interest} +\o +\l{http://www.x-query.com/mailman/listinfo/talk}{talk at x-query.com}. +\endlist + +\l{http://www.functx.com/functx/}{FunctX} has a collection of XQuery +functions that can be both useful and educational. + +This introduction contains many links to the specifications, which, of course, +are the ultimate source of information about XQuery. They can be a bit +difficult, though, so consider investing in a textbook: + +\list + + \o \l{http://www.w3.org/TR/xquery/}{XQuery 1.0: An XML Query + Language} - the main source for syntax and semantics. + + \o \l{http://www.w3.org/TR/xpath-functions/}{XQuery 1.0 and XPath + 2.0 Functions and Operators} - the builtin functions and operators. + +\endlist + +\section1 FAQ + +The answers to these frequently asked questions explain the causes of +several common mistakes that most beginners make. Reading through the +answers ahead of time might save you a lot of head scratching. + +\section2 Why didn't my path expression match anything? + +The most common cause of this bug is failure to declare one or more +namespaces in your XQuery. Consider the following query for selecting +all the examples in an XHTML document: + +\quotefile snippets/patternist/simpleHTML.xq + +It won't match anything because \c{index.html} is an XHTML file, and +all XHTML files declare the default namespace +\c{"http://www.w3.org/1999/xhtml"} in their top (\c{<html>}) element. +But the query doesn't declare this namespace, so the path expression +expands \c{html} to \c{{}html} and tries to match that expanded name. +But the actual expanded name is +\c{{http://www.w3.org/1999/xhtml}html}. One possible fix is to declare the +correct default namespace in the XQuery: + +\quotefile snippets/patternist/simpleXHTML.xq + +Another common cause of this bug is to confuse the \e{document node} +with the top element node. They are different. This query won't match +anything: + +\quotefile snippets/patternist/docPlainHTML.xq + +The \c{doc()} function returns the \e{document node}, not the top +element node (\c{<html>}). Don't forget to match the top element node +in the path expression: + +\quotefile snippets/patternist/docPlainHTML2.xq + +\section2 What if my input namespace is different from my output namespace? + +Just remember to declare both namespaces in your XQuery and use them +properly. Consider the following query, which is meant to generate +XHTML output from XML input: + +\quotefile snippets/patternist/embedDataInXHTML.xq + +We want the \c{<html>}, \c{<body>}, and \c{<p>} nodes we create in the +output to be in the standard XHTML namespace, so we declare the +default namespace to be \c{http://www.w3.org/1999/xhtml}. That's +correct for the output, but that same default namespace will also be +applied to the node names in the path expression we're trying to match +in the input (\c{/tests/test[@status = "failure"]}), which is wrong, +because the namespace used in \c{testResult.xml} is perhaps in the +empty namespace. So we must declare that namespace too, with a +namespace prefix, and then use the prefix with the node names in +the path expression. This one will probably work better: + +\quotefile snippets/patternist/embedDataInXHTML2.xq + +\section2 Why doesn't my return clause work? + +Recall that XQuery is an \e{expression-based} language, not +\e{statement-based}. Because an XQuery is a lot of expressions, +understanding XQuery expression precedence is very important. +Consider the following query: + +\quotefile snippets/patternist/forClause2.xq + +It looks ok, but it isn't. It is supposed to be a FLWOR expression +comprising a \e{for} clause and a \e{return} clause, but it isn't just +that. It \e{has} a FLWOR expression, certainly (with the \e{for} and +\e{return} clauses), but it \e{also} has an arithmetic expression +(\e{+ $d}) dangling at the end because we didn't enclose the return +expression in parentheses. + +Using parentheses to establish precedence is more important in XQuery +than in other languages, because XQuery is \e{expression-based}. In +In this case, without parantheses enclosing \c{$i + $d}, the return +clause only returns \c{$i}. The \c{+$d} will have the result of the +FLWOR expression as its left operand. And, since the scope of variable +\c{$d} ends at the end of the \e{return} clause, a variable out of +scope error will be reported. Correct these problems by using +parentheses. + +\quotefile snippets/patternist/forClause.xq + +\section2 Why didn't my expression get evaluated? + +You probably misplaced some curly braces. When you want an expression +evaluated inside an element constructor, enclose the expression in +curly braces. Without the curly braces, the expression will be +interpreted as text. Here is a \c{sum()} expression used in an \c{<e>} +element. The table shows cases where the curly braces are missing, +misplaced, and placed correctly: + +\table +\header + \o element constructor with expression... + \o evaluates to... + \row + \o <e>sum((1, 2, 3))</e> + \o <e>sum((1, 2, 3))</e> + \row + \o <e>sum({(1, 2, 3)})</e> + \o <e>sum(1 2 3)</e> + \row + \o <e>{sum((1, 2, 3))}</e> + \o <e>6</e> +\endtable + +\section2 My predicate is correct, so why doesn't it select the right stuff? + +Either you put your predicate in the wrong place in your path +expression, or you forgot to add some parentheses. Consider this +input file \c{doc.txt}: + +\quotefile snippets/patternist/doc.txt + +Suppose you want the first \c{<span>} element of every \c{<p>} +element. Apply a position filter (\c{[1]}) to the \c{/span} path step: + +\quotefile snippets/patternist/filterOnStep.xq + +Applying the \c{[1]} filter to the \c{/span} step returns the first +\c{<span>} element of each \c{<p>} element: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 41 + +\note: You can write the same query this way: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 44 + +Or you can reduce it right down to this: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 45 + +On the other hand, suppose you really want only one \c{<span>} +element, the first one in the document (i.e., you only want the first +\c{<span>} element in the first \c{<p>} element). Then you have to do +more filtering. There are two ways you can do it. You can apply the +\c{[1]} filter in the same place as above but enclose the path +expression in parentheses: + +\quotefile snippets/patternist/filterOnPath.xq + +Or you can apply a second position filter (\c{[1]} again) to the +\c{/p} path step: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 43 + +Either way the query will return only the first \c{<span>} element in +the document: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 42 + +\section2 Why doesn't my FLWOR behave as expected? + +The quick answer is you probably expected your XQuery FLWOR to behave +just like a C++ \e{for} loop. But they aren't the same. Consider a +simple example: + +\quotefile snippets/patternist/letOrderBy.xq + +This query evaluates to \e{4 -4 -2 2 -8 8}. The \e{for} clause does +set up a \e{for} loop style iteration, which does evaluate the rest of +the FLWOR multiple times, one time for each value returned by the +\e{in} expression. That much is similar to the C++ \e{for} loop. + +But consider the \e{return} clause. In C++ if you hit a \e{return} +statement, you break out of the \e{for} loop and return from the +function with one value. Not so in XQuery. The \e{return} clause is +the last clause of the FLWOR, and it means: \e{Append the return value +to the result list and then begin the next iteration of the FLWOR}. +When the \e{for} clause's \e{in} expression no longer returns a value, +the entire result list is returned. + +Next, consider the \e{order by} clause. It doesn't do any sorting on +each iteration of the FLWOR. It just evaluates its expression on each +iteration (\c{$a} in this case) to get an ordering value to map to the +result item from each iteration. These ordering values are kept in a +parallel list. The result list is sorted at the end using the parallel +list of ordering values. + +The last difference to note here is that the \e{let} clause does +\e{not} set up an iteration through a sequence of values like the +\e{for} clause does. The \e{let} clause isn't a sort of nested loop. +It isn't a loop at all. It is just a variable binding. On each +iteration, it binds the \e{entire} sequence of values on the right to +the variable on the left. In the example above, it binds (4 -4) to +\c{$b} on the first iteration, (-2 2) on the second iteration, and (-8 +8) on the third iteration. So the following query doesn't iterate +through anything, and doesn't do any ordering: + +\quotefile snippets/patternist/invalidLetOrderBy.xq + +It binds the entire sequence (2, 3, 1) to \c{$i} one time only; the +\e{order by} clause only has one thing to order and hence does +nothing, and the query evaluates to 2 3 1, the sequence assigned to +\c{$i}. + +\note We didn't include a \e{where} clause in the example. The +\e{where} clause is for filtering results. + +\section2 Why are my elements created in the wrong order? + +The short answer is your elements are \e{not} created in the wrong +order, because when appearing as operands to a path expression, +there is no correct order. Consider the following query, +which again uses the input file \c{doc.txt}: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 46 + +The query finds all the \c{<p>} elements in the file. For each \c{<p>} +element, it builds a \c{<p>} element in the output containing the +concatenated contents of all the \c{<p>} element's child \c{<span>} +elements. Running the query through \c{xmlpatterns} might produce the +following output, which is not sorted in the expected order. + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 47 + +You can use a \e{for} loop to ensure that the order of +the result set corresponds to the order of the input sequence: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 48 + +This version produces the same result set but in the expected order: + +\snippet snippets/code/doc_src_qtxmlpatterns.qdoc 49 + +\section2 Why can't I use \c{true} and \c{false} in my XQuery? + +You can, but not by just using the names \c{true} and \c{false} +directly, because they are \l{Name Tests} {name tests} although they look +like boolean constants. The simple way to create the boolean values is +to use the builtin functions \c{true()} and \c{false()} wherever +you want to use \c{true} and \c{false}. The other way is to invoke the +boolean constructor: + +\quotefile snippets/patternist/xsBooleanTrue.xq +*/ |