?? xml-sax-features-walkthrough.html
字號:
<p> <pre> #include <<a href="qxml-h.html">qxml.h</a>> #include <<a href="qptrstack-h.html">qptrstack.h</a>> class QListView; class QListViewItem; class QString;</pre><p> <pre> class StructureParser: public <a href="qxmldefaulthandler.html">QXmlDefaultHandler</a> {</pre><p> We derive it from the <a href="qxmldefaulthandler.html">QXmlDefaultHandler</a> class that implements a handler that simply does nothing. <p> <pre> public: StructureParser( <a href="qlistview.html">QListView</a> * );</pre><p> This makes it easy for us to implement only the functionalitywe in fact need. In our case this is the constructor thattakes a <a href="qlistview.html">QListView</a> as an argument,<p> <pre> bool startElement( const <a href="qstring.html">QString</a>&, const <a href="qstring.html">QString</a>&, const <a href="qstring.html">QString</a>& , const <a href="qxmlattributes.html">QXmlAttributes</a>& );</pre><p> the function to execute at the occurrence of element start tags(inherited from <a href="qxmlcontenthandler.html">QXmlContentHandler</a>), and<p> <pre> bool endElement( const <a href="qstring.html">QString</a>&, const <a href="qstring.html">QString</a>&, const <a href="qstring.html">QString</a>& );</pre><p> the code to run when an end tag occurs.<p> All we have to implement so far is content handling.<p> <pre> void setListView( <a href="qlistview.html">QListView</a> * );</pre><p> In addition we have a function that selects a listviewfor the output.<p> <pre> private: <a href="qptrstack.html">QPtrStack</a><QListViewItem> stack;</pre><p> Keep in mind that we write a SAX2 parser that doesn'thave an object model to keep all elements and attributesin memory. To display the elements and attributes in a tree like structure we must however keep track of all elementsthat haven't been closed yet. <p> To do this we use a LIFO stack of QListItems. An element will be added to the stack whenits start tag appears and removed as soon as its end tag is parsed.<p> <pre> <a href="qlistview.html">QListView</a> * table; };</pre><p> Apart from this we define a member variable that containsthe currently used listview.<p> <h3><a name="structureparser.cpp">The handler itself</a></h3><p> Now that we defined the API we have to implement the relevant functions.<p> <pre> #include "structureparser.h" #include <<a href="qstring-h.html">qstring.h</a>> #include <<a href="qlistview-h.html">qlistview.h</a>></pre><p> <pre> StructureParser::StructureParser( <a href="qlistview.html">QListView</a> * t ) : <a href="qxmldefaulthandler.html">QXmlDefaultHandler</a>() {</pre><p> First we have the constructor that takes a listview pointer asits argument.<p> <pre> setListView( t ); }</pre><p> All we have to do here is to prepare the argument <a href="qlistview.html">QListView</a>before usage. This we do with the <a href="#setListView()">setListView()</a> function.<p> <a name="setListView()"></a> <pre> void StructureParser::setListView( <a href="qlistview.html">QListView</a> * t ) { table = t;</pre><p> First we store the argument away.<p> <pre> table->setSorting( -1 );</pre><p> We want the elements to be listed as they appear in thedocument -- and not for example sorted alphabetically. That'swhy we switch off sorting at all.<p> <pre> table->addColumn( "Qualified name" ); table->addColumn( "Namespace" ); }</pre><p> The listview now consists of two columns: one for theelement's or attribute's qualified names and one fortheir namespace URIs. Columns are added from left to rightand with the title as an argument.<p> Now let's deal with XML content handling.<p> <pre> bool StructureParser::<a href="qxmlcontenthandler.html#startElement">startElement</a>( const <a href="qstring.html">QString</a>& namespaceURI, const <a href="qstring.html">QString</a>& , const <a href="qstring.html">QString</a>& qName, const <a href="qxmlattributes.html">QXmlAttributes</a>& attributes) {</pre><p> When we come across the start tag of an element the handler does the real work. Although <em>startElement</em> is called with fourarguments we keep track of only three: the namespace URIof the element, its qualified name and its attributes.If an element has no namespace assigned or if the featuresettings of the reader don't provide the handler withnamespace URIs at all <em>namespaceURI</em> contains an emptystring.<p> Note that we don't assign a variable to the second argument --we're simply not interested in the local name of the element.<p> <pre> <a href="qlistviewitem.html">QListViewItem</a> * element;</pre><p> Whenever an element occurs we want to show it in the listview.Therefore we define a <a href="qlistviewitem.html">QListViewItem</a> variable.<p> <pre> if ( ! stack.isEmpty() ){ <a href="qlistviewitem.html">QListViewItem</a> *lastChild = stack.top()->firstChild();</pre><p> As long as the element <em>stack</em> isn't empty the current elementis a child of the topmost (last unclosed) element on the stack. Thus wecreate a new <a href="qlistviewitem.html">QListViewItem</a> as a child of QPtrStack::stack.top() with the new element's qualified name in the first column and the accordingnamespace URI (or nothing) in the second one.<p> The <a href="qlistviewitem.html">QListViewItem</a> is usally inserted as the first child. This means that wewould get the elements in reverse order. So we first search for the lastchild of the QPtrStack::stack.top() element and insert it after thiselement.<p> In a valid XML document this applies to all elements exceptthe document root.<p> <pre> if ( lastChild ) { while ( lastChild-><a href="qlistviewitem.html#nextSibling">nextSibling</a>() ) lastChild = lastChild-><a href="qlistviewitem.html#nextSibling">nextSibling</a>(); } element = new <a href="qlistviewitem.html">QListViewItem</a>( stack.top(), lastChild, qName, namespaceURI ); } else { element = new <a href="qlistviewitem.html">QListViewItem</a>( table, qName, namespaceURI ); }</pre><p> The root element we have to handle separately because it isthe first element to go onto the <a href="qlistviewitem.html">QListViewItem</a> stack.Its listview item is therefore a direct child of the<em>table</em> listview itself.<p> <pre> stack.push( element );</pre><p> Now we put the element's listview item on top of the stack.<p> <pre> element-><a href="qlistviewitem.html#setOpen">setOpen</a>( TRUE );</pre><p> By default a <a href="qlistview.html">QListView</a> presents all of its nodes closed.The user may then click on the <em>+</em> icon to see the childentries.<p> We however want to see the entire element tree at once when we run the program.Therefore we open each listview item manually.<p> <pre> if ( attributes.<a href="qxmlattributes.html#length">length</a>() > 0 ) {</pre><p> What do we do if an element has attributes?<p> <pre> <a name="x2073"></a> for ( int i = 0 ; i < attributes.<a href="qxmlattributes.html#length">length</a>(); i++ ) { <a name="x2075"></a><a name="x2074"></a> new <a href="qlistviewitem.html">QListViewItem</a>( element, attributes.<a href="qxmlattributes.html#qName">qName</a>(i), attributes.<a href="qxmlattributes.html#uri">uri</a>(i) ); } }</pre><p> For each of them we create a new listview item to present the attribute'squalified name and the relevant namespace URI (or nothing). Obviously <em>attribute</em> is a child ofthe current <em>element</em>.<p> <pre> return TRUE; }</pre><p> To prevent the reader from throwing an error we have toreturn TRUE when we successfully dealt with anelement's start tag.<p> <pre> bool StructureParser::<a href="qxmlcontenthandler.html#endElement">endElement</a>( const <a href="qstring.html">QString</a>&, const <a href="qstring.html">QString</a>&, const <a href="qstring.html">QString</a>& ) { stack.pop();</pre><p> Whenever we come across an element's closing tag wehave to remove its listview item from the stack asit can't have children any longer.<p> <pre> return TRUE; }</pre><p> And so we're done.<p> <p>See also <a href="step-by-step-examples.html">Step-by-step Examples</a>.<!-- eof --><p><address><hr><div align=center><table width=100% cellspacing=0 border=0><tr><td>Copyright © 2002 <a href="http://www.trolltech.com">Trolltech</a><td><a href="http://www.trolltech.com/trademarks.html">Trademarks</a><td align=right><div align=right>Qt version 3.0.5</div></table></div></address></body></html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -