Difference between revisions of "Development/Tutorials/QtDOM Tutorial"

Jump to: navigation, search
(Add author name)
(Get rid of one more member to concentrate on the essential.)
Line 1: Line 1:
 +
[[Category:KDE4]]
 
= Short introduction to XML =
 
= Short introduction to XML =
  
Line 12: Line 13:
 
<holidayset country="at">
 
<holidayset country="at">
 
   <name>Holidays for Austria</name>
 
   <name>Holidays for Austria</name>
  <comment>This is an example and by far not complete.</comment>
 
 
   <holiday>
 
   <holiday>
 
     <name>New Year's Day</name>
 
     <name>New Year's Day</name>
 
     <date>2007-01-01</date>
 
     <date>2007-01-01</date>
    <comment>Happy new year!</comment>
 
 
   </holiday>
 
   </holiday>
 
   <holiday>
 
   <holiday>
Line 34: Line 33:
 
{
 
{
 
public:
 
public:
   Holiday( const QDate &d, const QString &n,
+
   Holiday() {}
          const QString &c = QString() )
+
      mDate(d), mName(n), mComment(c) {}
+
 
   ~Holiday() {}
 
   ~Holiday() {}
  
 
   QDate mDate;
 
   QDate mDate;
   QString mName, mComment;
+
   QString mName;
 
}
 
}
  
Line 49: Line 46:
 
   ~HolidaySet() {}
 
   ~HolidaySet() {}
  
   QString mCountry, mName, mComment;
+
   QString mCountry, mName;
 
   QList<Holiday> mHolidays;
 
   QList<Holiday> mHolidays;
 
}
 
}
Line 63: Line 60:
 
As there are only so many sensible names, sooner or later you will find out that you will use the same tagname or attribute name for different cases with different meanings. That is the point where namespaces come in.
 
As there are only so many sensible names, sooner or later you will find out that you will use the same tagname or attribute name for different cases with different meanings. That is the point where namespaces come in.
  
[[Category:KDE4]]
 
 
= Creating a simple XML file with Qt DOM =
 
= Creating a simple XML file with Qt DOM =
  
Line 99: Line 95:
 
   if ( !hs.mName.isEmpty() )  
 
   if ( !hs.mName.isEmpty() )  
 
     addElement( doc, holidaySetElement, "name", hs.mName );
 
     addElement( doc, holidaySetElement, "name", hs.mName );
  if ( !hs.mComment.isEmpty() )
 
    addElement( doc, holidaySetElement, "comment", hs.mComment );
 
  
 
   // Add each holiday as a <holiday>..</holiday> element
 
   // Add each holiday as a <holiday>..</holiday> element
Line 108: Line 102:
 
     addElement( doc, h, "name", (*i).mName );
 
     addElement( doc, h, "name", (*i).mName );
 
     addElement( doc, h, "date", (*i).mDate.toString( Qt::ISODate ) );
 
     addElement( doc, h, "date", (*i).mDate.toString( Qt::ISODate ) );
    if ( !(*i).mComment.isEmpty() )
 
      addElement( doc, h, "comment", (*i).mComment );
 
 
   }
 
   }
  
Line 122: Line 114:
 
<code xml>
 
<code xml>
 
<?xml version='1.0' encoding='UTF-8'?>
 
<?xml version='1.0' encoding='UTF-8'?>
<h:holidays xmlns:h="urn:kde:developer:tutorials:QtDom:holidays">
+
<h:holidays xmlns:h="urn:kde:developer:tutorials:QtDom:holidays" h:country="at">
  <h:holiday country="at">
+
  <h:holiday>
 
     <h:name>New Year's Day</h:name>
 
     <h:name>New Year's Day</h:name>
 
     <h:date>2007-01-01</h:date>
 
     <h:date>2007-01-01</h:date>
    <h:comment></h:comment>
 
 
   </h:holiday>
 
   </h:holiday>
 
   <h:holiday>
 
   <h:holiday>

Revision as of 15:04, 12 January 2007

Contents

Short introduction to XML

XML is a general structured format to store and exchange hierarchical data.

If you know HTML, you'll find XML quite similar (in fact, after some small modifications, a HTML file is a valid XML file): XML uses nested tags of the form <tagname>...</tagname> for tags with contents and <tagname/> for tags without content. Each tag can contain other tags, and the tag itself can have attributes of the form <tagname attribute=value>...</tagname>.

The name of the tags is not restricted (unlike HTML, which only defines a given set of proper HTML tags), so you can choose whatever name fits your name.

As an example, let us assume that you want to store holiday information into a file and use Qt to load or modify it. To get a feeling for how XML looks like, here is one possible format for such a holiday file: <?xml version='1.0' encoding='UTF-8'?> <holidayset country="at">

 <name>Holidays for Austria</name>
 <holiday>
   <name>New Year's Day</name>
   <date>2007-01-01</date>
 </holiday>
 <holiday>
   <name>Christmas</name>
   <date>2007-12-24</date>
 </holiday>

</holidayset> This file defines a holiday set for Austria (notice the country="at" attribute to the holidayset tag). The holiday set, enclosed in <holidayset>...</holidayset> contains two holidays, each enclosed with <holiday>...</holiday>. Each of these holiday elements contains the settings for that holiday enclosed in appropriately named tag.

Notice that we did use the same tag <name> inside the <holidayset> and inside the <holiday> tags. Also note that we implicitly used specially formated (ISO-formatted) contents for the date tags, without yet specifying it. Also note that we used quite generic names for the tags, which might become a problem with complexer structure, when we want to use the same name for different purposes.

We will use this example throughout this tutorial. In our application, we want to store the holiday set in the following class:

class Holiday { public:

 Holiday() {}
 ~Holiday() {}
 QDate mDate;
 QString mName;

}

class HolidaySet { public:

 HolidaySet( const QString &c ) : mCountry( c ) {}
 ~HolidaySet() {}
 QString mCountry, mName;
 QList<Holiday> mHolidays;

}

In production code, you would not make the member variables public and directly access them, but rather add accessors and setter functions: QDate date() { return mDate; } void setDate( const QDate &date ) { mDate = date; } To save space, I decided to neglect that rule of thumb here in this example. As this is a tutorial for XML and Qt DOM, I want to concentrate on the basics of Qt DOM and not on a good general programming style.

As there are only so many sensible names, sooner or later you will find out that you will use the same tagname or attribute name for different cases with different meanings. That is the point where namespaces come in.

Creating a simple XML file with Qt DOM

Let us first look at how to use the Qt classes to generate the XML for the holiday file from the HolidaySet class that you have in memory. For this purpose, Qt offers the classes QDomDocument to represent the whole document and QDomNode and QDomElement to represent each individual tag and attribute. As a line of code says more then a thousand words, let us look at some sample code to generate the DOM tree from the HolidaySet class:

/* Helper function to generate a DOM Element for the given DOM document

  and append it to the children of the given node. */

QDomElement addElement( QDomDocument &doc, QDomNode &node,

                       const QString &tag, 
                       const QString &value = QString::null )

{

 QDomElement el = doc.createElement( tag );
 node.appendChild( el );
 if ( !value.isNull() ) {
   QDomText txt = doc.createTextNode( value );
   el.appendChild( txt );
 }
 return el;

}


QString holidaySetToXML( const HolidaySet &hs ) {

 QDomDocument doc;
 // generate the <holidayset> tag as the root tag, add the country 
 // attribute if needed
 QDomElement holidaySetElement = addElement( doc, doc, "holidayset" );
 if ( !hs.mCountry.isEmpty() ) 
   holidaySetElement.setAttribute( "country", hs.mCountry );
 
 // Add the <name> and <comment> elements to the holidayset
 if ( !hs.mName.isEmpty() ) 
   addElement( doc, holidaySetElement, "name", hs.mName );
 // Add each holiday as a <holiday>..</holiday> element
 QList<Holiday>::iterator i;
 for ( i = hs.mHolidays.begin(); i != hs.mHolidays.end(); ++i) {
    QDomElement h = addElement( doc, holidaySetElement, "holiday" );
    addElement( doc, h, "name", (*i).mName );
    addElement( doc, h, "date", (*i).mDate.toString( Qt::ISODate ) );
 }
 return doc.toString();

}

Loading a simple XML file using Qt DOM

Introduction to XML Namespaces

<?xml version='1.0' encoding='UTF-8'?> <h:holidays xmlns:h="urn:kde:developer:tutorials:QtDom:holidays" h:country="at">

 <h:holiday>
   <h:name>New Year's Day</h:name>
   <h:date>2007-01-01</h:date>
 </h:holiday>
 <h:holiday>
   <h:name>Christmas</h:name>
   <h:date>2007-12-24</h:date>
 </h:holiday>

</h:holidays>

Generating XML documents with namespaces using Qt

Loading XML documents with namespaces using Qt

Loading XML documents using Qt and the SAX parser

Initial Author: Reinhold Kainhofer


KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal