<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- recipes.qdoc --> <title>Recipes Example | Qt XML Patterns 5.9</title> <link rel="stylesheet" type="text/css" href="style/offline-simple.css" /> <script type="text/javascript"> document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css"); // loading style sheet breaks anchors that were jumped to before // so force jumping to anchor again setTimeout(function() { var anchor = location.hash; // need to jump to different anchor first (e.g. none) location.hash = "#"; setTimeout(function() { location.hash = anchor; }, 0); }, 0); </script> </head> <body> <div class="header" id="qtdocheader"> <div class="main"> <div class="main-rounded"> <div class="navigationbar"> <table><tr> <td >Qt 5.9</td><td ><a href="qtxmlpatterns-index.html">Qt XML Patterns</a></td><td ><a href="xmlpattern-examples.html">Qt XML Patterns Examples</a></td><td >Recipes Example</td></tr></table><table class="buildversion"><tr> <td id="buildversion" width="100%" align="right">Qt 5.9.4 Reference Documentation</td> </tr></table> </div> </div> <div class="content"> <div class="line"> <div class="content mainContent"> <div class="sidebar"> <div class="toc"> <h3><a name="toc">Contents</a></h3> <ul> <li class="level1"><a href="#introduction">Introduction</a></li> <li class="level2"><a href="#the-user-interface">The User Interface</a></li> <li class="level2"><a href="#running-your-own-xqueries">Running your own XQueries</a></li> <li class="level1"><a href="#code-walk-through">Code Walk-Through</a></li> <li class="level2"><a href="#the-ui-class-querymainwindow">The UI Class: QueryMainWindow</a></li> </ul> </div> <div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title">Recipes Example</h1> <span class="subtitle"></span> <!-- $$$recipes-description --> <div class="descr"> <a name="details"></a> <p>The Recipes example shows how to use Qt XML Patterns to query XML data loaded from a file.</p> <a name="introduction"></a> <h2 id="introduction">Introduction</h2> <p>In this case, the XML data represents a cookbook, <code>cookbook.xml</code>, which contains <code><cookbook></code> as its document element, which in turn contains a sequence of <code><recipe></code> elements. This XML data is searched using queries stored in <a href="xmlprocessing.html">XQuery</a> files (<code>*.xq</code>).</p> <a name="the-user-interface"></a> <h3 >The User Interface</h3> <p>The UI for this example was created using Qt Designer:</p> <p class="centerAlign"><img src="images/recipes-example.png" alt="" /></p><p>The UI consists of three group boxes arranged vertically. The top one contains a text viewer that displays the XML text from the cookbook file. The middle group box contains a combo box for choosing the <a href="xquery-introduction.html">XQuery</a> to run and a text viewer for displaying the text of the selected <a href="xmlprocessing.html">XQuery</a>. The <code>.xq</code> files in the file list above are shown in the combo box menu. Choosing an <a href="xmlprocessing.html">XQuery</a> loads, parses, and runs the selected <a href="xmlprocessing.html">XQuery</a>. The query result is shown in the bottom group box's text viewer.</p> <a name="running-your-own-xqueries"></a> <h3 >Running your own XQueries</h3> <p>You can write your own <a href="xmlprocessing.html">XQuery</a> files and run them in the example program. The file <code>xmlpatterns/recipes/recipes.qrc</code> is the resource file for this example. It is used in <code>main.cpp</code> (<code>Q_INIT_RESOURCE(recipes);</code>). It lists the <a href="xmlprocessing.html">XQuery</a> files (<code>.xq</code>) that can be selected in the combobox.</p> <pre class="qml"> <!DOCTYPE RCC><RCC version="1.0"> <qresource> <file>files/cookbook.xml</file> <file>files/allRecipes.xq</file> <file>files/liquidIngredientsInSoup.xq</file> <file>files/mushroomSoup.xq</file> <file>files/preparationLessThan30.xq</file> <file>files/preparationTimes.xq</file> </qresource> </RCC> </pre> <p>To add your own queries to the example's combobox, store your <code>.xq</code> files in the <code>examples/xmlpatterns/recipes/files</code> directory and add them to <code>recipes.qrc</code> as shown above.</p> <a name="code-walk-through"></a> <h2 id="code-walk-through">Code Walk-Through</h2> <p>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:</p> <pre class="cpp"> <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span><span class="operator">*</span> argv<span class="operator">[</span><span class="operator">]</span>) { Q_INIT_RESOURCE(recipes); <span class="type">QApplication</span> app(argc<span class="operator">,</span> argv); QueryMainWindow<span class="operator">*</span> <span class="keyword">const</span> queryWindow <span class="operator">=</span> <span class="keyword">new</span> QueryMainWindow; queryWindow<span class="operator">-</span><span class="operator">></span>show(); <span class="keyword">return</span> app<span class="operator">.</span>exec(); } </pre> <a name="the-ui-class-querymainwindow"></a> <h3 >The UI Class: QueryMainWindow</h3> <p>The example's UI is a conventional Qt GUI application inheriting QMainWindow and the class generated by Qt Designer:</p> <pre class="cpp"> <span class="keyword">class</span> QueryMainWindow : <span class="keyword">public</span> <span class="type">QMainWindow</span><span class="operator">,</span> <span class="keyword">private</span> Ui<span class="operator">::</span>QueryWidget { Q_OBJECT <span class="keyword">public</span>: QueryMainWindow(); <span class="keyword">public</span> <span class="keyword">slots</span>: <span class="type">void</span> displayQuery(<span class="type">int</span> index); <span class="keyword">private</span>: <span class="type">QComboBox</span><span class="operator">*</span> ui_defaultQueries; <span class="type">void</span> evaluate(<span class="keyword">const</span> <span class="type">QString</span> <span class="operator">&</span>str); <span class="type">void</span> loadInputFile(); }; </pre> <p>The constructor finds the window's combo box child widget and connects its currentIndexChanged() signal to the window's <code>displayQuery()</code> slot. It then calls <code>loadInputFile()</code> to load <code>cookbook.xml</code> and display its contents in the top group box's text viewer . Finally, it finds the <a href="xmlprocessing.html">XQuery</a> files (<code>.xq</code>) and adds each one to the combo box menu.</p> <pre class="cpp"> QueryMainWindow<span class="operator">::</span>QueryMainWindow() : ui_defaultQueries(<span class="number">0</span>) { setupUi(<span class="keyword">this</span>); <span class="keyword">new</span> XmlSyntaxHighlighter(findChild<span class="operator"><</span><span class="type">QTextEdit</span><span class="operator">*</span><span class="operator">></span>(<span class="string">"inputTextEdit"</span>)<span class="operator">-</span><span class="operator">></span>document()); <span class="keyword">new</span> XmlSyntaxHighlighter(findChild<span class="operator"><</span><span class="type">QTextEdit</span><span class="operator">*</span><span class="operator">></span>(<span class="string">"outputTextEdit"</span>)<span class="operator">-</span><span class="operator">></span>document()); ui_defaultQueries <span class="operator">=</span> findChild<span class="operator"><</span><span class="type">QComboBox</span><span class="operator">*</span><span class="operator">></span>(<span class="string">"defaultQueries"</span>); <span class="type">QMetaObject</span><span class="operator">::</span>connectSlotsByName(<span class="keyword">this</span>); connect(ui_defaultQueries<span class="operator">,</span> SIGNAL(currentIndexChanged(<span class="type">int</span>))<span class="operator">,</span> SLOT(displayQuery(<span class="type">int</span>))); loadInputFile(); <span class="keyword">const</span> <span class="type">QStringList</span> queries(<span class="type">QDir</span>(<span class="string">":/files/"</span><span class="operator">,</span> <span class="string">"*.xq"</span>)<span class="operator">.</span>entryList()); <span class="type">int</span> len <span class="operator">=</span> queries<span class="operator">.</span>count(); <span class="keyword">for</span>(<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator"><</span> len; <span class="operator">+</span><span class="operator">+</span>i) ui_defaultQueries<span class="operator">-</span><span class="operator">></span>addItem(queries<span class="operator">.</span>at(i)); <span class="keyword">if</span> (len <span class="operator">></span> <span class="number">0</span>) displayQuery(<span class="number">0</span>); } </pre> <p>The work is done in the <a href="qtxmlpatterns-recipes-example.html#displayquery-slot">displayQuery()</a> slot and the <a href="qtxmlpatterns-recipes-example.html#evaluate-function">evaluate()</a> function it calls. <a href="qtxmlpatterns-recipes-example.html#displayquery-slot">displayQuery()</a> loads and displays the selected query file and passes the <a href="xmlprocessing.html">XQuery</a> text to <a href="qtxmlpatterns-recipes-example.html#evaluate-function">evaluate()</a>.</p> <a name="displayquery-slot"></a><pre class="cpp"> <span class="type">void</span> QueryMainWindow<span class="operator">::</span>displayQuery(<span class="type">int</span> index) { <span class="type">QFile</span> queryFile(<span class="type">QString</span>(<span class="string">":files/"</span>) <span class="operator">+</span> ui_defaultQueries<span class="operator">-</span><span class="operator">></span>itemText(index)); queryFile<span class="operator">.</span>open(<span class="type">QIODevice</span><span class="operator">::</span>ReadOnly); <span class="keyword">const</span> <span class="type">QString</span> query(<span class="type">QString</span><span class="operator">::</span>fromLatin1(queryFile<span class="operator">.</span>readAll())); findChild<span class="operator"><</span><span class="type">QTextEdit</span><span class="operator">*</span><span class="operator">></span>(<span class="string">"queryTextEdit"</span>)<span class="operator">-</span><span class="operator">></span>setPlainText(query); evaluate(query); } </pre> <p><a href="qtxmlpatterns-recipes-example.html#evaluate-function">evaluate()</a> demonstrates the standard Qt XML Patterns usage pattern. First, an instance of <a href="qxmlquery.html">QXmlQuery</a> is created (<code>query</code>). The <code>query's</code> <a href="qxmlquery.html#bindVariable">bindVariable()</a> function is then called to bind the <code>cookbook.xml</code> file to the <a href="xmlprocessing.html">XQuery</a> variable <code>inputDocument</code>. <i>After</i> the variable is bound, <a href="qxmlquery.html#setQuery">setQuery()</a> is called to pass the <a href="xmlprocessing.html">XQuery</a> text to the <code>query</code>.</p> <p><b>Note: </b><a href="qxmlquery.html#setQuery">setQuery()</a> must be called <i>after</i> <a href="qxmlquery.html#bindVariable">bindVariable()</a>.</p><p>Passing the <a href="xmlprocessing.html">XQuery</a> to <a href="qxmlquery.html#setQuery">setQuery()</a> causes Qt XML Patterns to parse the <a href="xmlprocessing.html">XQuery</a>. <a href="qxmlquery.html#isValid">QXmlQuery::isValid</a>() is called to ensure that the <a href="xmlprocessing.html">XQuery</a> was correctly parsed.</p> <a name="evaluate-function"></a><pre class="cpp"> <span class="type">void</span> QueryMainWindow<span class="operator">::</span>evaluate(<span class="keyword">const</span> <span class="type">QString</span> <span class="operator">&</span>str) { <span class="type">QFile</span> sourceDocument; sourceDocument<span class="operator">.</span>setFileName(<span class="string">":/files/cookbook.xml"</span>); sourceDocument<span class="operator">.</span>open(<span class="type">QIODevice</span><span class="operator">::</span>ReadOnly); <span class="type">QByteArray</span> outArray; <span class="type">QBuffer</span> buffer(<span class="operator">&</span>outArray); buffer<span class="operator">.</span>open(<span class="type">QIODevice</span><span class="operator">::</span>ReadWrite); <span class="type"><a href="qxmlquery.html">QXmlQuery</a></span> query; query<span class="operator">.</span>bindVariable(<span class="string">"inputDocument"</span><span class="operator">,</span> <span class="operator">&</span>sourceDocument); query<span class="operator">.</span>setQuery(str); <span class="keyword">if</span> (<span class="operator">!</span>query<span class="operator">.</span>isValid()) <span class="keyword">return</span>; <span class="type"><a href="qxmlformatter.html">QXmlFormatter</a></span> formatter(query<span class="operator">,</span> <span class="operator">&</span>buffer); <span class="keyword">if</span> (<span class="operator">!</span>query<span class="operator">.</span>evaluateTo(<span class="operator">&</span>formatter)) <span class="keyword">return</span>; buffer<span class="operator">.</span>close(); findChild<span class="operator"><</span><span class="type">QTextEdit</span><span class="operator">*</span><span class="operator">></span>(<span class="string">"outputTextEdit"</span>)<span class="operator">-</span><span class="operator">></span>setPlainText(<span class="type">QString</span><span class="operator">::</span>fromUtf8(outArray<span class="operator">.</span>constData())); } </pre> <p>If the <a href="xmlprocessing.html">XQuery</a> is valid, an instance of <a href="qxmlformatter.html">QXmlFormatter</a> is created to format the query result as XML into a QBuffer. To evaluate the <a href="xmlprocessing.html">XQuery</a>, an overload of <a href="qxmlquery.html#evaluateTo">evaluateTo()</a> is called that takes a <a href="qabstractxmlreceiver.html">QAbstractXmlReceiver</a> for its output (<a href="qxmlformatter.html">QXmlFormatter</a> inherits <a href="qabstractxmlreceiver.html">QAbstractXmlReceiver</a>). Finally, the formatted XML result is displayed in the UI's bottom text view.</p> <p><b>Note: </b>Each <a href="xmlprocessing.html">XQuery</a> <code>.xq</code> file must declare the <code>$inputDocument</code> variable to represent the <code>cookbook.xml</code> document:</p><pre class="cpp plain"> (: All ingredients for Mushroom Soup. :) declare variable $inputDocument external; doc($inputDocument)/cookbook/recipe[@xml:id = "MushroomSoup"]/ingredient/ <p>{@name, @quantity}</p> </pre> <p><b>Note: </b>If you add add your own query.xq files, you must declare the <code>$inputDocument</code> and use it as shown above.</p><p>Files:</p> <ul> <li><a href="qtxmlpatterns-recipes-querymainwindow-cpp.html">recipes/querymainwindow.cpp</a></li> <li><a href="qtxmlpatterns-recipes-querymainwindow-h.html">recipes/querymainwindow.h</a></li> <li><a href="qtxmlpatterns-recipes-files-allrecipes-xq.html">recipes/files/allRecipes.xq</a></li> <li><a href="qtxmlpatterns-recipes-files-cookbook-xml.html">recipes/files/cookbook.xml</a></li> <li><a href="qtxmlpatterns-recipes-files-liquidingredientsinsoup-xq.html">recipes/files/liquidIngredientsInSoup.xq</a></li> <li><a href="qtxmlpatterns-recipes-files-mushroomsoup-xq.html">recipes/files/mushroomSoup.xq</a></li> <li><a href="qtxmlpatterns-recipes-files-preparationlessthan30-xq.html">recipes/files/preparationLessThan30.xq</a></li> <li><a href="qtxmlpatterns-recipes-files-preparationtimes-xq.html">recipes/files/preparationTimes.xq</a></li> <li><a href="qtxmlpatterns-recipes-forms-querywidget-ui.html">recipes/forms/querywidget.ui</a></li> <li><a href="qtxmlpatterns-recipes-forms-querywidget-mobiles-ui.html">recipes/forms/querywidget_mobiles.ui</a></li> <li><a href="qtxmlpatterns-recipes-main-cpp.html">recipes/main.cpp</a></li> <li><a href="qtxmlpatterns-recipes-recipes-pro.html">recipes/recipes.pro</a></li> <li><a href="qtxmlpatterns-recipes-recipes-qrc.html">recipes/recipes.qrc</a></li> </ul> </div> <!-- @@@recipes --> </div> </div> </div> </div> </div> <div class="footer"> <p> <acronym title="Copyright">©</acronym> 2017 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners.<br> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br> Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners. </p> </div> </body> </html>