|  | Home · Overviews · Examples

# QXmlStreamReader Class Reference
[com.trolltech.qt.xml module]

The `QXmlStreamReader` class provides a fast well-formed XML parser with a simple streaming API. More...

## Detailed Description

The `QXmlStreamReader` class provides a fast well-formed XML parser with a simple streaming API.

`QXmlStreamReader` is a faster and more convenient replacement for Qt's own SAX parser (see `QXmlSimpleReader`), and in some cases also for applications that would previously use a DOM tree (see `QDomDocument`). `QXmlStreamReader` reads data either from a `QIODevice` (see `setDevice`), or from a raw `QByteArray` (see `addData`). With `QXmlStreamWriter`, Qt provides a related class for writing XML.

The basic concept of a stream reader is to report an XML document as a stream of tokens, similar to SAX. The main difference between `QXmlStreamReader` and SAX is how these XML tokens are reported. With SAX, the application must provide handlers that receive so-called XML events from the parser at the parser's convenience. With `QXmlStreamReader`, the application code itself drives the loop and pulls tokens from the reader one after another as it needs them. This is done by calling `readNext`, which makes the reader read from the input stream until it has completed a new token, and then returns its `tokenType`. A set of convenient functions like `isStartElement` or `text` then allows to examine this token, and to obtain information about what has been read. The big advantage of the pulling approach is the possibility to build recursive descent parsers, meaning you can split your XML parsing code easily into different methods or classes. This makes it easy to keep track of the application's own state when parsing XML.

A typical loop with `QXmlStreamReader` looks like this:

        QXmlStreamReader xml;
        ...
        while (!xml.atEnd()) {
              xml.readNext();
              ... // do processing
        }
        if (xml.hasError()) {
              ... // do error handling
        }

`QXmlStreamReader` is a well-formed XML 1.0 parser that does not include external parsed entities. As long as no error occurs, the application code can thus be assured that the data provided by the stream reader satisfies the W3C's criteria for well-formed XML. For example, you can be certain that all tags are indeed nested and closed properly, that references to internal entities have been replaced with the correct replacement text, and that attributes have been normalized or added according to the internal subset of the DTD.

If an error does occur while parsing, `atEnd` returns true and `error` returns the kind of error that occurred. `hasError` can also be used to check whether an error has occurred. The functions `errorString`, `lineNumber`, `columnNumber`, and `characterOffset` make it possible to generate a verbose human-understandable error or warning message. In order to simplify application code, `QXmlStreamReader` contains a `raiseError` mechanism that makes it possible to raise custom errors that then trigger the same error handling code path.

The `QXmlStream Bookmarks Example` illustrates how to use the recursive descent technique with a subclassed stream reader to read an XML bookmark file (XBEL).

### Namespaces

QXmlStream understands and resolves XML namespaces. E.g. in case of a `StartElement`, `namespaceUri` returns the namespace the element is in, and `name` returns the element's local name. The combination of `namespaceUri` and name uniquely identifies an element. If a namespace prefix was not declared in the XML entities parsed by the reader, the `namespaceUri` is empty.

If you parse XML data that does not utilize namespaces according to the XML specification or doesn't use namespaces at all, you can use the element's `qualifiedName` instead. A qualified name is the element's prefix followed by colon followed by the element's local name - exactly like the element appears in the raw XML data. Since the mapping `namespaceUri` to prefix is neither unique nor universal, `qualifiedName` should be avoided for namespace-compliant XML data.

In order to parse standalone documents that do use undeclared namespace prefixes, you can turn off namespace processing completely with the `namespaceProcessing` property.

### Incremental parsing

`QXmlStreamReader` is an incremental parser. If you can't parse the entire input in one go (for example, it is huge, or is being delivered over a network connection), data can be fed to the parser in pieces. If the reader runs out of data before the document has been parsed completely, it reports a `PrematureEndOfDocumentError`. Once more data has arrived, either through the device or because it has been added with `addData`, it recovers from that error and continues parsing on the next call to read().

For example, if you read data from the network using `QHttp`, you would connect its readyRead() signal to a custom slot. In this slot, you read all available data with readAll() and pass it to the XML stream reader using `addData`. Then you call your custom parsing function that reads the XML events from the reader.

### Performance and memory consumption

`QXmlStreamReader` is memory-conservative by design, since it doesn't store the entire XML document tree in memory, but only the current token at the time it is reported. In addition, `QXmlStreamReader` avoids the many small string allocations that it normally takes to map an XML document to a convenient and Qt-ish API. It does this by reporting all string data as QStringRef rather than real `QString` objects. QStringRef is a thin wrapper around `QString` substrings that provides a subset of the `QString` API without the memory allocation and reference-counting overhead. Calling toString() on any of those objects returns an equivalent real `QString` object.