1
/****************************************************************************
2
** $Id: qxml.cpp,v 1.1 2004/02/29 00:05:06 justin Exp $
4
** Implementation of QXmlSimpleReader and related classes.
8
** Copyright (C) 1992-2004 Trolltech AS. All rights reserved.
10
** This file is part of the xml module of the Qt GUI Toolkit.
12
** This file may be distributed under the terms of the Q Public License
13
** as defined by Trolltech AS of Norway and appearing in the file
14
** LICENSE.QPL included in the packaging of this file.
16
** This file may be distributed and/or modified under the terms of the
17
** GNU General Public License version 2 as published by the Free Software
18
** Foundation and appearing in the file LICENSE.GPL included in the
19
** packaging of this file.
21
** Licensees holding valid Qt Enterprise Edition licenses may use this
22
** file in accordance with the Qt Commercial License Agreement provided
25
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29
** information about Qt Commercial License Agreements.
30
** See http://www.trolltech.com/qpl/ for QPL licensing information.
31
** See http://www.trolltech.com/gpl/ for GPL licensing information.
33
** Contact info@trolltech.com if any conditions of this licensing are
36
**********************************************************************/
39
#include "qtextcodec.h"
42
#include "qptrstack.h"
44
#include "qvaluestack.h"
46
// needed for QT_TRANSLATE_NOOP:
53
//#define QT_QXML_DEBUG
55
// Error strings for the XML reader
56
#define XMLERR_OK QT_TRANSLATE_NOOP( "QXml", "no error occurred" )
57
#define XMLERR_ERRORBYCONSUMER QT_TRANSLATE_NOOP( "QXml", "error triggered by consumer" )
58
#define XMLERR_UNEXPECTEDEOF QT_TRANSLATE_NOOP( "QXml", "unexpected end of file" )
59
#define XMLERR_MORETHANONEDOCTYPE QT_TRANSLATE_NOOP( "QXml", "more than one document type definition" )
60
#define XMLERR_ERRORPARSINGELEMENT QT_TRANSLATE_NOOP( "QXml", "error occurred while parsing element" )
61
#define XMLERR_TAGMISMATCH QT_TRANSLATE_NOOP( "QXml", "tag mismatch" )
62
#define XMLERR_ERRORPARSINGCONTENT QT_TRANSLATE_NOOP( "QXml", "error occurred while parsing content" )
63
#define XMLERR_UNEXPECTEDCHARACTER QT_TRANSLATE_NOOP( "QXml", "unexpected character" )
64
#define XMLERR_INVALIDNAMEFORPI QT_TRANSLATE_NOOP( "QXml", "invalid name for processing instruction" )
65
#define XMLERR_VERSIONEXPECTED QT_TRANSLATE_NOOP( "QXml", "version expected while reading the XML declaration" )
66
#define XMLERR_WRONGVALUEFORSDECL QT_TRANSLATE_NOOP( "QXml", "wrong value for standalone declaration" )
67
#define XMLERR_EDECLORSDDECLEXPECTED QT_TRANSLATE_NOOP( "QXml", "encoding declaration or standalone declaration expected while reading the XML declaration" )
68
#define XMLERR_SDDECLEXPECTED QT_TRANSLATE_NOOP( "QXml", "standalone declaration expected while reading the XML declaration" )
69
#define XMLERR_ERRORPARSINGDOCTYPE QT_TRANSLATE_NOOP( "QXml", "error occurred while parsing document type definition" )
70
#define XMLERR_LETTEREXPECTED QT_TRANSLATE_NOOP( "QXml", "letter is expected" )
71
#define XMLERR_ERRORPARSINGCOMMENT QT_TRANSLATE_NOOP( "QXml", "error occurred while parsing comment" )
72
#define XMLERR_ERRORPARSINGREFERENCE QT_TRANSLATE_NOOP( "QXml", "error occurred while parsing reference" )
73
#define XMLERR_INTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP( "QXml", "internal general entity reference not allowed in DTD" )
74
#define XMLERR_EXTERNALGENERALENTITYINAV QT_TRANSLATE_NOOP( "QXml", "external parsed general entity reference not allowed in attribute value" )
75
#define XMLERR_EXTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP( "QXml", "external parsed general entity reference not allowed in DTD" )
76
#define XMLERR_UNPARSEDENTITYREFERENCE QT_TRANSLATE_NOOP( "QXml", "unparsed entity reference in wrong context" )
77
#define XMLERR_RECURSIVEENTITIES QT_TRANSLATE_NOOP( "QXml", "recursive entities" )
78
#define XMLERR_ERRORINTEXTDECL QT_TRANSLATE_NOOP( "QXml", "error in the text declaration of an external entity" )
80
// the constants for the lookup table
81
static const signed char cltWS = 0; // white space
82
static const signed char cltPer = 1; // %
83
static const signed char cltAmp = 2; // &
84
static const signed char cltGt = 3; // >
85
static const signed char cltLt = 4; // <
86
static const signed char cltSlash = 5; // /
87
static const signed char cltQm = 6; // ?
88
static const signed char cltEm = 7; // !
89
static const signed char cltDash = 8; // -
90
static const signed char cltCB = 9; // ]
91
static const signed char cltOB = 10; // [
92
static const signed char cltEq = 11; // =
93
static const signed char cltDq = 12; // "
94
static const signed char cltSq = 13; // '
95
static const signed char cltUnknown = 14;
97
// character lookup table
98
static const signed char charLookupTable[256]={
99
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
108
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
109
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
126
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
135
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
136
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
137
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
146
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
147
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
148
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
149
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
150
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
151
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
152
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
153
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
154
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
155
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
156
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
157
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
158
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
159
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
160
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
161
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
162
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
163
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
164
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
165
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF
170
// local helper functions
174
This function strips the TextDecl [77] ("<?xml ...?>") from the string \a
175
str. The stripped version is stored in \a str. If this function finds an
176
invalid TextDecl, it returns FALSE, otherwise TRUE.
178
This function is used for external entities since those can include an
179
TextDecl that must be stripped before inserting the entity.
181
static bool stripTextDecl( QString& str )
183
QString textDeclStart( "<?xml" );
184
if ( str.startsWith( textDeclStart ) ) {
185
QRegExp textDecl(QString::fromLatin1(
187
"(version\\s*=\\s*((['\"])[-a-zA-Z0-9_.:]+\\3))?"
189
"(encoding\\s*=\\s*((['\"])[A-Za-z][-a-zA-Z0-9_.]*\\6))?"
192
QString strTmp = str.replace( textDecl, "" );
193
if ( strTmp.length() != str.length() )
194
return FALSE; // external entity has wrong TextDecl
201
class QXmlAttributesPrivate
204
class QXmlInputSourcePrivate
207
class QXmlParseExceptionPrivate
210
class QXmlLocatorPrivate
213
class QXmlDefaultHandlerPrivate
218
\class QXmlParseException qxml.h
220
\brief The QXmlParseException class is used to report errors with
221
the QXmlErrorHandler interface.
222
\if defined(commercial)
223
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
229
The XML subsystem constructs an instance of this class when it
230
detects an error. You can retrieve the place where the error
231
occurred using systemId(), publicId(), lineNumber() and
232
columnNumber(), along with the error message().
234
\sa QXmlErrorHandler QXmlReader
238
\fn QXmlParseException::QXmlParseException( const QString& name, int c, int l, const QString& p, const QString& s )
240
Constructs a parse exception with the error string \a name for
241
column \a c and line \a l for the public identifier \a p and the
242
system identifier \a s.
246
Returns the error message.
248
QString QXmlParseException::message() const
253
Returns the column number where the error occurred.
255
int QXmlParseException::columnNumber() const
260
Returns the line number where the error occurred.
262
int QXmlParseException::lineNumber() const
267
Returns the public identifier where the error occurred.
269
QString QXmlParseException::publicId() const
274
Returns the system identifier where the error occurred.
276
QString QXmlParseException::systemId() const
283
\class QXmlLocator qxml.h
285
\brief The QXmlLocator class provides the XML handler classes with
286
information about the parsing position within a file.
287
\if defined(commercial)
288
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
294
The reader reports a QXmlLocator to the content handler before it
295
starts to parse the document. This is done with the
296
QXmlContentHandler::setDocumentLocator() function. The handler
297
classes can now use this locator to get the position (lineNumber()
298
and columnNumber()) that the reader has reached.
304
QXmlLocator::QXmlLocator()
311
QXmlLocator::~QXmlLocator()
316
\fn int QXmlLocator::columnNumber()
318
Returns the column number (starting at 1) or -1 if there is no
319
column number available.
323
\fn int QXmlLocator::lineNumber()
325
Returns the line number (starting at 1) or -1 if there is no line
329
class QXmlSimpleReaderLocator : public QXmlLocator
332
QXmlSimpleReaderLocator( QXmlSimpleReader* parent )
336
~QXmlSimpleReaderLocator()
342
return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 );
346
return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 );
348
// QString getPublicId()
349
// QString getSystemId()
352
QXmlSimpleReader *reader;
355
/*********************************************
357
* QXmlNamespaceSupport
359
*********************************************/
361
class QXmlNamespaceSupportPrivate
364
QXmlNamespaceSupportPrivate()
366
ns = new QMap<QString, QString>;
367
ns->insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace
370
~QXmlNamespaceSupportPrivate()
372
nsStack.setAutoDelete( TRUE );
377
QPtrStack<QMap<QString, QString> > nsStack;
378
QMap<QString, QString> *ns;
382
\class QXmlNamespaceSupport qxml.h
384
\brief The QXmlNamespaceSupport class is a helper class for XML
385
readers which want to include namespace support.
386
\if defined(commercial)
387
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
393
You can set the prefix for the current namespace with setPrefix(),
394
and get the list of current prefixes (or those for a given URI)
395
with prefixes(). The namespace URI is available from uri(). Use
396
pushContext() to start a new namespace context, and popContext()
397
to return to the previous namespace context. Use splitName() or
398
processName() to split a name into its prefix and local name.
400
See also the \link xml.html#sax2Namespaces namespace description\endlink.
404
Constructs a QXmlNamespaceSupport.
406
QXmlNamespaceSupport::QXmlNamespaceSupport()
408
d = new QXmlNamespaceSupportPrivate;
412
Destroys a QXmlNamespaceSupport.
414
QXmlNamespaceSupport::~QXmlNamespaceSupport()
420
This function declares a prefix \a pre in the current namespace
421
context to be the namespace URI \a uri. The prefix remains in
422
force until this context is popped, unless it is shadowed in a
425
Note that there is an asymmetry in this library. prefix() does not
426
return the default "" prefix, even if you have declared one; to
427
check for a default prefix, you must look it up explicitly using
428
uri(). This asymmetry exists to make it easier to look up prefixes
429
for attribute names, where the default prefix is not allowed.
431
void QXmlNamespaceSupport::setPrefix( const QString& pre, const QString& uri )
434
d->ns->insert( "", uri );
436
d->ns->insert( pre, uri );
441
Returns one of the prefixes mapped to the namespace URI \a uri.
443
If more than one prefix is currently mapped to the same URI, this
444
function makes an arbitrary selection; if you want all of the
445
prefixes, use prefixes() instead.
447
Note: to check for a default prefix, use the uri() function with
450
QString QXmlNamespaceSupport::prefix( const QString& uri ) const
452
QMap<QString, QString>::ConstIterator itc, it = d->ns->begin();
453
while ( (itc=it) != d->ns->end() ) {
455
if ( itc.data() == uri && !itc.key().isEmpty() )
462
Looks up the prefix \a prefix in the current context and returns
463
the currently-mapped namespace URI. Use the empty string ("") for
464
the default namespace.
466
QString QXmlNamespaceSupport::uri( const QString& prefix ) const
468
const QString& returi = (*d->ns)[ prefix ];
473
Splits the name \a qname at the ':' and returns the prefix in \a
474
prefix and the local name in \a localname.
478
void QXmlNamespaceSupport::splitName( const QString& qname,
479
QString& prefix, QString& localname ) const
483
for( pos=0; pos<qname.length(); pos++ ) {
484
if ( qname.at(pos) == ':' )
488
prefix = qname.left( pos );
489
localname = qname.mid( pos+1 );
493
Processes a raw XML 1.0 name in the current context by removing
494
the prefix and looking it up among the prefixes currently
497
\a qname is the raw XML 1.0 name to be processed. \a isAttribute
498
is TRUE if the name is an attribute name.
500
This function stores the namespace URI in \a nsuri (which will be
501
set to QString::null if the raw name has an undeclared prefix),
502
and stores the local name (without prefix) in \a localname (which
503
will be set to QString::null if no namespace is in use).
505
Note that attribute names are processed differently than element
506
names: an unprefixed element name gets the default namespace (if
507
any), while an unprefixed element name does not.
509
void QXmlNamespaceSupport::processName( const QString& qname,
511
QString& nsuri, QString& localname ) const
513
uint pos = qname.find( ':' );
514
if ( pos < qname.length() ) {
516
nsuri = uri( qname.left( pos ) );
517
localname = qname.mid( pos+1 );
521
nsuri = QString::null; // attributes don't take default namespace
523
nsuri = uri( "" ); // get default namespace
530
Returns a list of all the prefixes currently declared.
532
If there is a default prefix, this function does not return it in
533
the list; check for the default prefix using uri() with an
536
Note that if you want to iterate over the list, you should iterate
539
QStringList list = myXmlNamespaceSupport.prefixes();
540
QStringList::Iterator it = list.begin();
541
while( it != list.end() ) {
547
QStringList QXmlNamespaceSupport::prefixes() const
551
QMap<QString, QString>::ConstIterator itc, it = d->ns->begin();
552
while ( (itc=it) != d->ns->end() ) {
554
if ( !itc.key().isEmpty() )
555
list.append( itc.key() );
563
Returns a list of all prefixes currently declared for the
564
namespace URI \a uri.
566
The "xml:" prefix is included. If you only want one prefix that is
567
mapped to the namespace URI, and you don't care which one you get,
568
use the prefix() function instead.
570
Note: the empty (default) prefix is never included in this list;
571
to check for the presence of a default namespace, use uri() with
574
Note that if you want to iterate over the list, you should iterate
577
QStringList list = myXmlNamespaceSupport.prefixes( "" );
578
QStringList::Iterator it = list.begin();
579
while( it != list.end() ) {
585
QStringList QXmlNamespaceSupport::prefixes( const QString& uri ) const
589
QMap<QString, QString>::ConstIterator itc, it = d->ns->begin();
590
while ( (itc=it) != d->ns->end() ) {
592
if ( itc.data() == uri && !itc.key().isEmpty() )
593
list.append( itc.key() );
599
Starts a new namespace context.
601
Normally, you should push a new context at the beginning of each
602
XML element: the new context automatically inherits the
603
declarations of its parent context, and it also keeps track of
604
which declarations were made within this context.
608
void QXmlNamespaceSupport::pushContext()
610
d->nsStack.push( new QMap<QString, QString>(*d->ns) );
614
Reverts to the previous namespace context.
616
Normally, you should pop the context at the end of each XML
617
element. After popping the context, all namespace prefix mappings
618
that were previously in force are restored.
622
void QXmlNamespaceSupport::popContext()
625
if( !d->nsStack.isEmpty() )
626
d->ns = d->nsStack.pop();
630
Resets this namespace support object ready for reuse.
632
void QXmlNamespaceSupport::reset()
635
d = new QXmlNamespaceSupportPrivate;
640
/*********************************************
644
*********************************************/
647
\class QXmlAttributes qxml.h
649
\brief The QXmlAttributes class provides XML attributes.
650
\if defined(commercial)
651
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
657
If attributes are reported by QXmlContentHandler::startElement()
658
this class is used to pass the attribute values.
660
Use index() to locate the position of an attribute in the list,
661
count() to retrieve the number of attributes, and clear() to
662
remove the attributes. New attributes can be added with append().
663
Use type() to get an attribute's type and value() to get its
664
value. The attribute's name is available from localName() or
665
qName(), and its namespace URI from uri().
670
\fn QXmlAttributes::QXmlAttributes()
672
Constructs an empty attribute list.
676
\fn QXmlAttributes::~QXmlAttributes()
678
Destroys the attributes object.
682
Looks up the index of an attribute by the qualified name \a qName.
684
Returns the index of the attribute or -1 if it wasn't found.
686
See also the \link xml.html#sax2Namespaces namespace description\endlink.
688
int QXmlAttributes::index( const QString& qName ) const
690
return qnameList.findIndex( qName );
696
Looks up the index of an attribute by a namespace name.
698
\a uri specifies the namespace URI, or an empty string if the name
699
has no namespace URI. \a localPart specifies the attribute's local
702
Returns the index of the attribute, or -1 if it wasn't found.
704
See also the \link xml.html#sax2Namespaces namespace description\endlink.
706
int QXmlAttributes::index( const QString& uri, const QString& localPart ) const
710
uriTmp = QString::null;
713
uint count = (uint)uriList.count(); // ### size_t/int cast
714
for ( uint i=0; i<count; i++ ) {
715
if ( uriList[i] == uriTmp && localnameList[i] == localPart )
722
Returns the number of attributes in the list.
726
int QXmlAttributes::length() const
728
return (int)valueList.count();
732
\fn int QXmlAttributes::count() const
734
Returns the number of attributes in the list. This function is
735
equivalent to length().
739
Looks up an attribute's local name for the attribute at position
740
\a index. If no namespace processing is done, the local name is
743
See also the \link xml.html#sax2Namespaces namespace description\endlink.
745
QString QXmlAttributes::localName( int index ) const
747
return localnameList[index];
751
Looks up an attribute's XML 1.0 qualified name for the attribute
752
at position \a index.
754
See also the \link xml.html#sax2Namespaces namespace description\endlink.
756
QString QXmlAttributes::qName( int index ) const
758
return qnameList[index];
762
Looks up an attribute's namespace URI for the attribute at
763
position \a index. If no namespace processing is done or if the
764
attribute has no namespace, the namespace URI is QString::null.
766
See also the \link xml.html#sax2Namespaces namespace description\endlink.
768
QString QXmlAttributes::uri( int index ) const
770
return uriList[index];
774
Looks up an attribute's type for the attribute at position \a
777
Currently only "CDATA" is returned.
779
QString QXmlAttributes::type( int ) const
787
Looks up an attribute's type for the qualified name \a qName.
789
Currently only "CDATA" is returned.
791
QString QXmlAttributes::type( const QString& ) const
799
Looks up an attribute's type by namespace name.
801
\a uri specifies the namespace URI and \a localName specifies the
802
local name. If the name has no namespace URI, use an empty string
805
Currently only "CDATA" is returned.
807
QString QXmlAttributes::type( const QString&, const QString& ) const
813
Looks up an attribute's value for the attribute at position \a
816
QString QXmlAttributes::value( int index ) const
818
return valueList[index];
824
Looks up an attribute's value for the qualified name \a qName.
826
See also the \link xml.html#sax2Namespaces namespace description\endlink.
828
QString QXmlAttributes::value( const QString& qName ) const
830
int i = index( qName );
832
return QString::null;
833
return valueList[ i ];
839
Looks up an attribute's value by namespace name.
841
\a uri specifies the namespace URI, or an empty string if the name
842
has no namespace URI. \a localName specifies the attribute's local
845
See also the \link xml.html#sax2Namespaces namespace description\endlink.
847
QString QXmlAttributes::value( const QString& uri, const QString& localName ) const
849
int i = index( uri, localName );
851
return QString::null;
852
return valueList[ i ];
856
Clears the list of attributes.
860
void QXmlAttributes::clear()
864
localnameList.clear();
869
Appends a new attribute entry to the list of attributes. The
870
qualified name of the attribute is \a qName, the namespace URI is
871
\a uri and the local name is \a localPart. The value of the
872
attribute is \a value.
874
\sa qName() uri() localName() value()
876
void QXmlAttributes::append( const QString &qName, const QString &uri, const QString &localPart, const QString &value )
878
qnameList.append( qName );
879
uriList.append( uri );
880
localnameList.append( localPart);
881
valueList.append( value );
885
/*********************************************
889
*********************************************/
892
\class QXmlInputSource qxml.h
894
\brief The QXmlInputSource class provides the input data for the
895
QXmlReader subclasses.
896
\if defined(commercial)
897
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
903
All subclasses of QXmlReader read the input XML document from this
906
This class recognizes the encoding of the data by reading the
907
encoding declaration in the XML file if it finds one, and reading
908
the data using the corresponding encoding. If it does not find an
909
encoding declaration, then it assumes that the data is either in
910
UTF-8 or UTF-16, depending on whether it can find a byte-order
913
There are two ways to populate the input source with data: you can
914
construct it with a QIODevice* so that the input source reads the
915
data from that device. Or you can set the data explicitly with one
916
of the setData() functions.
918
Usually you either construct a QXmlInputSource that works on a
919
QIODevice* or you construct an empty QXmlInputSource and set the
920
data with setData(). There are only rare occasions where you would
921
want to mix both methods.
923
The QXmlReader subclasses use the next() function to read the
924
input character by character. If you want to start from the
925
beginning again, use reset().
927
The functions data() and fetchData() are useful if you want to do
928
something with the data other than parsing, e.g. displaying the
929
raw XML file. The benefit of using the QXmlInputClass in such
930
cases is that it tries to use the correct encoding.
932
\sa QXmlReader QXmlSimpleReader
935
// the following two are guaranteed not to be a character
936
const QChar QXmlInputSource::EndOfData = QChar((ushort)0xfffe);
937
const QChar QXmlInputSource::EndOfDocument = QChar((ushort)0xffff);
940
Common part of the constructors.
942
void QXmlInputSource::init()
947
setData( QString::null );
952
Constructs an input source which contains no data.
956
QXmlInputSource::QXmlInputSource()
962
Constructs an input source and gets the data from device \a dev.
963
If \a dev is not open, it is opened in read-only mode. If \a dev
964
is 0 or it is not possible to read from the device, the input
965
source will contain no data.
967
\sa setData() fetchData() QIODevice
969
QXmlInputSource::QXmlInputSource( QIODevice *dev )
977
Constructs an input source and gets the data from the text stream \a stream.
979
QXmlInputSource::QXmlInputSource( QTextStream& stream )
982
inputStream = &stream;
987
Constructs an input source and gets the data from the file \a file. If the
988
file cannot be read the input source is empty.
990
QXmlInputSource::QXmlInputSource( QFile& file )
1000
QXmlInputSource::~QXmlInputSource()
1006
Returns the next character of the input source. If this function
1007
reaches the end of available data, it returns
1008
QXmlInputSource::EndOfData. If you call next() after that, it
1009
tries to fetch more data by calling fetchData(). If the
1010
fetchData() call results in new data, this function returns the
1011
first character of that data; otherwise it returns
1012
QXmlInputSource::EndOfDocument.
1014
\sa reset() fetchData() QXmlSimpleReader::parse() QXmlSimpleReader::parseContinue()
1016
QChar QXmlInputSource::next()
1018
if ( pos >= length ) {
1019
if ( nextReturnedEndOfData ) {
1020
nextReturnedEndOfData = FALSE;
1022
if ( pos >= length ) {
1023
return EndOfDocument;
1027
nextReturnedEndOfData = TRUE;
1030
return unicode[pos++];
1034
This function sets the position used by next() to the beginning of
1035
the data returned by data(). This is useful if you want to use the
1036
input source for more than one parse.
1040
void QXmlInputSource::reset()
1042
nextReturnedEndOfData = FALSE;
1047
Returns the data the input source contains or QString::null if the
1048
input source does not contain any data.
1050
\sa setData() QXmlInputSource() fetchData()
1052
QString QXmlInputSource::data()
1058
Sets the data of the input source to \a dat.
1060
If the input source already contains data, this function deletes
1065
void QXmlInputSource::setData( const QString& dat )
1068
unicode = dat.unicode();
1070
length = str.length();
1071
nextReturnedEndOfData = FALSE;
1077
The data \a dat is passed through the correct text-codec, before
1080
void QXmlInputSource::setData( const QByteArray& dat )
1082
setData( fromRawData( dat ) );
1086
This function reads more data from the device that was set during
1087
construction. If the input source already contained data, this
1088
function deletes that data first.
1090
This object contains no data after a call to this function if the
1091
object was constructed without a device to read data from or if
1092
this function was not able to get more data from the device.
1094
There are two occasions where a fetch is done implicitly by
1095
another function call: during construction (so that the object
1096
starts out with some initial data where available), and during a
1097
call to next() (if the data had run out).
1099
You don't normally need to use this function if you use next().
1101
\sa data() next() QXmlInputSource()
1103
void QXmlInputSource::fetchData()
1107
if ( inputDevice != 0 ) {
1108
if ( inputDevice->isOpen() || inputDevice->open( IO_ReadOnly ) )
1109
rawData = inputDevice->readAll();
1110
} else if ( inputStream != 0 ) {
1111
if ( inputStream->device()->isDirectAccess() ) {
1112
rawData = inputStream->device()->readAll();
1115
const int bufsize = 512;
1116
while ( !inputStream->device()->atEnd() ) {
1117
rawData.resize( nread + bufsize );
1118
nread += inputStream->device()->readBlock( rawData.data()+nread, bufsize );
1120
rawData.resize( nread );
1123
setData( fromRawData( rawData ) );
1127
This function reads the XML file from \a data and tries to
1128
recognize the encoding. It converts the raw data \a data into a
1129
QString and returns it. It tries its best to get the correct
1130
encoding for the XML file.
1132
If \a beginning is TRUE, this function assumes that the data
1133
starts at the beginning of a new XML document and looks for an
1134
encoding declaration. If \a beginning is FALSE, it converts the
1135
raw data using the encoding determined from prior calls.
1137
QString QXmlInputSource::fromRawData( const QByteArray &data, bool beginning )
1139
if ( data.size() == 0 )
1140
return QString::null;
1145
if ( encMapper == 0 ) {
1146
QTextCodec *codec = 0;
1147
// look for byte order mark and read the first 5 characters
1148
if ( data.size() >= 2 &&
1149
( ((uchar)data.at(0)==(uchar)0xfe &&
1150
(uchar)data.at(1)==(uchar)0xff ) ||
1151
((uchar)data.at(0)==(uchar)0xff &&
1152
(uchar)data.at(1)==(uchar)0xfe ) )) {
1153
codec = QTextCodec::codecForMib( 1000 ); // UTF-16
1155
codec = QTextCodec::codecForMib( 106 ); // UTF-8
1158
return QString::null;
1160
encMapper = codec->makeDecoder();
1161
QString input = encMapper->toUnicode( data.data(), data.size() );
1162
// ### unexpected EOF? (for incremental parsing)
1163
// starts the document with an XML declaration?
1164
if ( input.find("<?xml") == 0 ) {
1165
// try to find out if there is an encoding
1166
int endPos = input.find( ">" );
1167
int pos = input.find( "encoding" );
1168
if ( pos < endPos && pos != -1 ) {
1172
if ( pos > endPos ) {
1175
} while( input[pos] != '"' && input[pos] != '\'' );
1177
while( input[pos] != '"' && input[pos] != '\'' ) {
1178
encoding += input[pos];
1180
if ( pos > endPos ) {
1185
codec = QTextCodec::codecForName( encoding );
1190
encMapper = codec->makeDecoder();
1191
return encMapper->toUnicode( data.data(), data.size() );
1196
return encMapper->toUnicode( data.data(), data.size() );
1200
/*********************************************
1202
* QXmlDefaultHandler
1204
*********************************************/
1207
\class QXmlContentHandler qxml.h
1209
\brief The QXmlContentHandler class provides an interface to
1210
report the logical content of XML data.
1211
\if defined(commercial)
1212
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
1218
If the application needs to be informed of basic parsing events,
1219
it can implement this interface and activate it using
1220
QXmlReader::setContentHandler(). The reader can then report basic
1221
document-related events like the start and end of elements and
1222
character data through this interface.
1224
The order of events in this interface is very important, and
1225
mirrors the order of information in the document itself. For
1226
example, all of an element's content (character data, processing
1227
instructions, and sub-elements) appears, in order, between the
1228
startElement() event and the corresponding endElement() event.
1230
The class QXmlDefaultHandler provides a default implementation for
1231
this interface; subclassing from the QXmlDefaultHandler class is
1232
very convenient if you only want to be informed of some parsing
1235
The startDocument() function is called at the start of the
1236
document, and endDocument() is called at the end. Before parsing
1237
begins setDocumentLocator() is called. For each element
1238
startElement() is called, with endElement() being called at the
1239
end of each element. The characters() function is called with
1240
chunks of character data; ignorableWhitespace() is called with
1241
chunks of whitespace and processingInstruction() is called with
1242
processing instructions. If an entity is skipped skippedEntity()
1243
is called. At the beginning of prefix-URI scopes
1244
startPrefixMapping() is called.
1246
See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
1248
\sa QXmlDTDHandler QXmlDeclHandler QXmlEntityResolver QXmlErrorHandler
1253
\fn void QXmlContentHandler::setDocumentLocator( QXmlLocator* locator )
1255
The reader calls this function before it starts parsing the
1256
document. The argument \a locator is a pointer to a QXmlLocator
1257
which allows the application to get the parsing position within
1260
Do not destroy the \a locator; it is destroyed when the reader is
1261
destroyed. (Do not use the \a locator after the reader is
1266
\fn bool QXmlContentHandler::startDocument()
1268
The reader calls this function when it starts parsing the
1269
document. The reader calls this function just once, after the call
1270
to setDocumentLocator(), and before any other functions in this
1271
class or in the QXmlDTDHandler class are called.
1273
If this function returns FALSE the reader stops parsing and
1274
reports an error. The reader uses the function errorString() to
1275
get the error message.
1281
\fn bool QXmlContentHandler::endDocument()
1283
The reader calls this function after it has finished parsing. It
1284
is called just once, and is the last handler function called. It
1285
is called after the reader has read all input or has abandoned
1286
parsing because of a fatal error.
1288
If this function returns FALSE the reader stops parsing and
1289
reports an error. The reader uses the function errorString() to
1290
get the error message.
1296
\fn bool QXmlContentHandler::startPrefixMapping( const QString& prefix, const QString& uri )
1298
The reader calls this function to signal the begin of a prefix-URI
1299
namespace mapping scope. This information is not necessary for
1300
normal namespace processing since the reader automatically
1301
replaces prefixes for element and attribute names.
1303
Note that startPrefixMapping() and endPrefixMapping() calls are
1304
not guaranteed to be properly nested relative to each other: all
1305
startPrefixMapping() events occur before the corresponding
1306
startElement() event, and all endPrefixMapping() events occur
1307
after the corresponding endElement() event, but their order is not
1308
otherwise guaranteed.
1310
The argument \a prefix is the namespace prefix being declared and
1311
the argument \a uri is the namespace URI the prefix is mapped to.
1313
If this function returns FALSE the reader stops parsing and
1314
reports an error. The reader uses the function errorString() to
1315
get the error message.
1317
See also the \link xml.html#sax2Namespaces namespace description\endlink.
1319
\sa endPrefixMapping()
1323
\fn bool QXmlContentHandler::endPrefixMapping( const QString& prefix )
1325
The reader calls this function to signal the end of a prefix
1326
mapping for the prefix \a prefix.
1328
If this function returns FALSE the reader stops parsing and
1329
reports an error. The reader uses the function errorString() to
1330
get the error message.
1332
See also the \link xml.html#sax2Namespaces namespace description\endlink.
1334
\sa startPrefixMapping()
1338
\fn bool QXmlContentHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts )
1340
The reader calls this function when it has parsed a start element
1343
There is a corresponding endElement() call when the corresponding
1344
end element tag is read. The startElement() and endElement() calls
1345
are always nested correctly. Empty element tags (e.g. \c{<x/>})
1346
cause a startElement() call to be immediately followed by an
1349
The attribute list provided only contains attributes with explicit
1350
values. The attribute list contains attributes used for namespace
1351
declaration (i.e. attributes starting with xmlns) only if the
1352
namespace-prefix property of the reader is TRUE.
1354
The argument \a namespaceURI is the namespace URI, or
1355
QString::null if the element has no namespace URI or if no
1356
namespace processing is done. \a localName is the local name
1357
(without prefix), or QString::null if no namespace processing is
1358
done, \a qName is the qualified name (with prefix) and \a atts are
1359
the attributes attached to the element. If there are no
1360
attributes, \a atts is an empty attributes object.
1362
If this function returns FALSE the reader stops parsing and
1363
reports an error. The reader uses the function errorString() to
1364
get the error message.
1366
See also the \link xml.html#sax2Namespaces namespace description\endlink.
1372
\fn bool QXmlContentHandler::endElement( const QString& namespaceURI, const QString& localName, const QString& qName )
1374
The reader calls this function when it has parsed an end element
1375
tag with the qualified name \a qName, the local name \a localName
1376
and the namespace URI \a namespaceURI.
1378
If this function returns FALSE the reader stops parsing and
1379
reports an error. The reader uses the function errorString() to
1380
get the error message.
1382
See also the \link xml.html#sax2Namespaces namespace description\endlink.
1388
\fn bool QXmlContentHandler::characters( const QString& ch )
1390
The reader calls this function when it has parsed a chunk of
1391
character data (either normal character data or character data
1392
inside a CDATA section; if you need to distinguish between those
1393
two types you must use QXmlLexicalHandler::startCDATA() and
1394
QXmlLexicalHandler::endCDATA()). The character data is reported in
1397
Some readers report whitespace in element content using the
1398
ignorableWhitespace() function rather than using this one.
1400
A reader may report the character data of an element in more than
1401
one chunk; e.g. a reader might want to report "a\<b" in three
1402
characters() events ("a ", "\<" and " b").
1404
If this function returns FALSE the reader stops parsing and
1405
reports an error. The reader uses the function errorString() to
1406
get the error message.
1410
\fn bool QXmlContentHandler::ignorableWhitespace( const QString& ch )
1412
Some readers may use this function to report each chunk of
1413
whitespace in element content. The whitespace is reported in \a ch.
1415
If this function returns FALSE the reader stops parsing and
1416
reports an error. The reader uses the function errorString() to
1417
get the error message.
1421
\fn bool QXmlContentHandler::processingInstruction( const QString& target, const QString& data )
1423
The reader calls this function when it has parsed a processing
1426
\a target is the target name of the processing instruction and \a
1427
data is the data in the processing instruction.
1429
If this function returns FALSE the reader stops parsing and
1430
reports an error. The reader uses the function errorString() to
1431
get the error message.
1435
\fn bool QXmlContentHandler::skippedEntity( const QString& name )
1437
Some readers may skip entities if they have not seen the
1438
declarations (e.g. because they are in an external DTD). If they
1439
do so they report that they skipped the entity called \a name by
1440
calling this function.
1442
If this function returns FALSE the reader stops parsing and
1443
reports an error. The reader uses the function errorString() to
1444
get the error message.
1448
\fn QString QXmlContentHandler::errorString()
1450
The reader calls this function to get an error string, e.g. if any
1451
of the handler functions returns FALSE.
1456
\class QXmlErrorHandler qxml.h
1458
\brief The QXmlErrorHandler class provides an interface to report
1460
\if defined(commercial)
1461
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
1467
If you want your application to report errors to the user or to
1468
perform customized error handling, you should subclass this class.
1470
You can set the error handler with QXmlReader::setErrorHandler().
1472
Errors can be reported using warning(), error() and fatalError(),
1473
with the error text being reported with errorString().
1475
See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
1477
\sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
1482
\fn bool QXmlErrorHandler::warning( const QXmlParseException& exception )
1484
A reader might use this function to report a warning. Warnings are
1485
conditions that are not errors or fatal errors as defined by the
1486
XML 1.0 specification. Details of the warning are stored in \a
1489
If this function returns FALSE the reader stops parsing and
1490
reports an error. The reader uses the function errorString() to
1491
get the error message.
1495
\fn bool QXmlErrorHandler::error( const QXmlParseException& exception )
1497
A reader might use this function to report a recoverable error. A
1498
recoverable error corresponds to the definiton of "error" in
1499
section 1.2 of the XML 1.0 specification. Details of the error are
1500
stored in \a exception.
1502
The reader must continue to provide normal parsing events after
1503
invoking this function.
1505
If this function returns FALSE the reader stops parsing and
1506
reports an error. The reader uses the function errorString() to
1507
get the error message.
1511
\fn bool QXmlErrorHandler::fatalError( const QXmlParseException& exception )
1513
A reader must use this function to report a non-recoverable error.
1514
Details of the error are stored in \a exception.
1516
If this function returns TRUE the reader might try to go on
1517
parsing and reporting further errors; but no regular parsing
1518
events are reported.
1522
\fn QString QXmlErrorHandler::errorString()
1524
The reader calls this function to get an error string if any of
1525
the handler functions returns FALSE.
1530
\class QXmlDTDHandler qxml.h
1532
\brief The QXmlDTDHandler class provides an interface to report
1533
DTD content of XML data.
1534
\if defined(commercial)
1535
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
1541
If an application needs information about notations and unparsed
1542
entities, it can implement this interface and register an instance
1543
with QXmlReader::setDTDHandler().
1545
Note that this interface includes only those DTD events that the
1546
XML recommendation requires processors to report, i.e. notation
1547
and unparsed entity declarations using notationDecl() and
1548
unparsedEntityDecl() respectively.
1550
See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
1552
\sa QXmlDeclHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
1557
\fn bool QXmlDTDHandler::notationDecl( const QString& name, const QString& publicId, const QString& systemId )
1559
The reader calls this function when it has parsed a notation
1562
The argument \a name is the notation name, \a publicId is the
1563
notation's public identifier and \a systemId is the notation's
1566
If this function returns FALSE the reader stops parsing and
1567
reports an error. The reader uses the function errorString() to
1568
get the error message.
1572
\fn bool QXmlDTDHandler::unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName )
1574
The reader calls this function when it finds an unparsed entity
1577
The argument \a name is the unparsed entity's name, \a publicId is
1578
the entity's public identifier, \a systemId is the entity's system
1579
identifier and \a notationName is the name of the associated
1582
If this function returns FALSE the reader stops parsing and
1583
reports an error. The reader uses the function errorString() to
1584
get the error message.
1588
\fn QString QXmlDTDHandler::errorString()
1590
The reader calls this function to get an error string if any of
1591
the handler functions returns FALSE.
1596
\class QXmlEntityResolver qxml.h
1598
\brief The QXmlEntityResolver class provides an interface to
1599
resolve external entities contained in XML data.
1600
\if defined(commercial)
1601
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
1607
If an application needs to implement customized handling for
1608
external entities, it must implement this interface, i.e.
1609
resolveEntity(), and register it with
1610
QXmlReader::setEntityResolver().
1612
See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
1614
\sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlErrorHandler
1619
\fn bool QXmlEntityResolver::resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource*& ret )
1621
The reader calls this function before it opens any external
1622
entity, except the top-level document entity. The application may
1623
request the reader to resolve the entity itself (\a ret is 0) or
1624
to use an entirely different input source (\a ret points to the
1627
The reader deletes the input source \a ret when it no longer needs
1628
it, so you should allocate it on the heap with \c new.
1630
The argument \a publicId is the public identifier of the external
1631
entity, \a systemId is the system identifier of the external
1632
entity and \a ret is the return value of this function. If \a ret
1633
is 0 the reader should resolve the entity itself, if it is
1634
non-zero it must point to an input source which the reader uses
1637
If this function returns FALSE the reader stops parsing and
1638
reports an error. The reader uses the function errorString() to
1639
get the error message.
1643
\fn QString QXmlEntityResolver::errorString()
1645
The reader calls this function to get an error string if any of
1646
the handler functions returns FALSE.
1651
\class QXmlLexicalHandler qxml.h
1653
\brief The QXmlLexicalHandler class provides an interface to
1654
report the lexical content of XML data.
1655
\if defined(commercial)
1656
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
1662
The events in the lexical handler apply to the entire document,
1663
not just to the document element, and all lexical handler events
1664
appear between the content handler's startDocument and endDocument
1667
You can set the lexical handler with
1668
QXmlReader::setLexicalHandler().
1670
This interface's design is based on the the SAX2 extension
1673
The interface provides the startDTD(), endDTD(), startEntity(),
1674
endEntity(), startCDATA(), endCDATA() and comment() functions.
1676
See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
1678
\sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
1683
\fn bool QXmlLexicalHandler::startDTD( const QString& name, const QString& publicId, const QString& systemId )
1685
The reader calls this function to report the start of a DTD
1686
declaration, if any. It reports the name of the document type in
1687
\a name, the public identifier in \a publicId and the system
1688
identifier in \a systemId.
1690
If the public identifier is missing, \a publicId is set to
1691
QString::null. If the system identifier is missing, \a systemId is
1692
set to QString::null. Note that it is not valid XML to have a
1693
public identifier but no system identifier; in such cases a parse
1696
All declarations reported through QXmlDTDHandler or
1697
QXmlDeclHandler appear between the startDTD() and endDTD() calls.
1699
If this function returns FALSE the reader stops parsing and
1700
reports an error. The reader uses the function errorString() to
1701
get the error message.
1707
\fn bool QXmlLexicalHandler::endDTD()
1709
The reader calls this function to report the end of a DTD
1710
declaration, if any.
1712
If this function returns FALSE the reader stops parsing and
1713
reports an error. The reader uses the function errorString() to
1714
get the error message.
1720
\fn bool QXmlLexicalHandler::startEntity( const QString& name )
1722
The reader calls this function to report the start of an entity
1725
Note that if the entity is unknown, the reader reports it through
1726
QXmlContentHandler::skippedEntity() and not through this
1729
If this function returns FALSE the reader stops parsing and
1730
reports an error. The reader uses the function errorString() to
1731
get the error message.
1733
\sa endEntity() QXmlSimpleReader::setFeature()
1737
\fn bool QXmlLexicalHandler::endEntity( const QString& name )
1739
The reader calls this function to report the end of an entity
1742
For every startEntity() call, there is a corresponding endEntity()
1743
call. The calls to startEntity() and endEntity() are properly
1746
If this function returns FALSE the reader stops parsing and
1747
reports an error. The reader uses the function errorString() to
1748
get the error message.
1750
\sa startEntity() QXmlContentHandler::skippedEntity() QXmlSimpleReader::setFeature()
1754
\fn bool QXmlLexicalHandler::startCDATA()
1756
The reader calls this function to report the start of a CDATA
1757
section. The content of the CDATA section is reported through the
1758
QXmlContentHandler::characters() function. This function is
1759
intended only to report the boundary.
1761
If this function returns FALSE the reader stops parsing and
1762
reports an error. The reader uses the function errorString() to
1763
get the error message.
1769
\fn bool QXmlLexicalHandler::endCDATA()
1771
The reader calls this function to report the end of a CDATA
1774
If this function returns FALSE the reader stops parsing and reports
1775
an error. The reader uses the function errorString() to get the error
1778
\sa startCDATA() QXmlContentHandler::characters()
1782
\fn bool QXmlLexicalHandler::comment( const QString& ch )
1784
The reader calls this function to report an XML comment anywhere
1785
in the document. It reports the text of the comment in \a ch.
1787
If this function returns FALSE the reader stops parsing and
1788
reports an error. The reader uses the function errorString() to
1789
get the error message.
1793
\fn QString QXmlLexicalHandler::errorString()
1795
The reader calls this function to get an error string if any of
1796
the handler functions returns FALSE.
1801
\class QXmlDeclHandler qxml.h
1803
\brief The QXmlDeclHandler class provides an interface to report declaration
1804
content of XML data.
1805
\if defined(commercial)
1806
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
1812
You can set the declaration handler with
1813
QXmlReader::setDeclHandler().
1815
This interface is based on the SAX2 extension DeclHandler.
1817
The interface provides attributeDecl(), internalEntityDecl() and
1818
externalEntityDecl() functions.
1820
See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
1822
\sa QXmlDTDHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
1827
\fn bool QXmlDeclHandler::attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value )
1829
The reader calls this function to report an attribute type
1830
declaration. Only the effective (first) declaration for an
1831
attribute is reported.
1833
The reader passes the name of the associated element in \a eName
1834
and the name of the attribute in \a aName. It passes a string that
1835
represents the attribute type in \a type and a string that
1836
represents the attribute default in \a valueDefault. This string
1837
is one of "#IMPLIED", "#REQUIRED", "#FIXED" or QString::null (if
1838
none of the others applies). The reader passes the attribute's
1839
default value in \a value. If no default value is specified in the
1840
XML file, \a value is QString::null.
1842
If this function returns FALSE the reader stops parsing and
1843
reports an error. The reader uses the function errorString() to
1844
get the error message.
1848
\fn bool QXmlDeclHandler::internalEntityDecl( const QString& name, const QString& value )
1850
The reader calls this function to report an internal entity
1851
declaration. Only the effective (first) declaration is reported.
1853
The reader passes the name of the entity in \a name and the value
1854
of the entity in \a value.
1856
If this function returns FALSE the reader stops parsing and
1857
reports an error. The reader uses the function errorString() to
1858
get the error message.
1862
\fn bool QXmlDeclHandler::externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId )
1864
The reader calls this function to report a parsed external entity
1865
declaration. Only the effective (first) declaration for each
1868
The reader passes the name of the entity in \a name, the public
1869
identifier in \a publicId and the system identifier in \a
1870
systemId. If there is no public identifier specified, it passes
1871
QString::null in \a publicId.
1873
If this function returns FALSE the reader stops parsing and
1874
reports an error. The reader uses the function errorString() to
1875
get the error message.
1879
\fn QString QXmlDeclHandler::errorString()
1881
The reader calls this function to get an error string if any of
1882
the handler functions returns FALSE.
1887
\class QXmlDefaultHandler qxml.h
1889
\brief The QXmlDefaultHandler class provides a default implementation of all
1890
the XML handler classes.
1891
\if defined(commercial)
1892
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
1898
Very often we are only interested in parts of the things that the
1899
reader reports. This class implements a default behaviour for the
1900
handler classes (i.e. most of the time do nothing). Usually this
1901
is the class you subclass for implementing your own customized
1904
See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
1906
\sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
1907
QXmlErrorHandler QXmlLexicalHandler
1911
\fn QXmlDefaultHandler::QXmlDefaultHandler()
1916
\fn QXmlDefaultHandler::~QXmlDefaultHandler()
1926
void QXmlDefaultHandler::setDocumentLocator( QXmlLocator* )
1935
bool QXmlDefaultHandler::startDocument()
1945
bool QXmlDefaultHandler::endDocument()
1955
bool QXmlDefaultHandler::startPrefixMapping( const QString&, const QString& )
1965
bool QXmlDefaultHandler::endPrefixMapping( const QString& )
1975
bool QXmlDefaultHandler::startElement( const QString&, const QString&,
1976
const QString&, const QXmlAttributes& )
1986
bool QXmlDefaultHandler::endElement( const QString&, const QString&,
1997
bool QXmlDefaultHandler::characters( const QString& )
2007
bool QXmlDefaultHandler::ignorableWhitespace( const QString& )
2017
bool QXmlDefaultHandler::processingInstruction( const QString&,
2028
bool QXmlDefaultHandler::skippedEntity( const QString& )
2038
bool QXmlDefaultHandler::warning( const QXmlParseException& )
2048
bool QXmlDefaultHandler::error( const QXmlParseException& )
2058
bool QXmlDefaultHandler::fatalError( const QXmlParseException& )
2068
bool QXmlDefaultHandler::notationDecl( const QString&, const QString&,
2079
bool QXmlDefaultHandler::unparsedEntityDecl( const QString&, const QString&,
2080
const QString&, const QString& )
2088
Sets \a ret to 0, so that the reader uses the system identifier
2089
provided in the XML document.
2091
bool QXmlDefaultHandler::resolveEntity( const QString&, const QString&,
2092
QXmlInputSource*& ret )
2101
Returns the default error string.
2103
QString QXmlDefaultHandler::errorString()
2105
return QString( XMLERR_ERRORBYCONSUMER );
2113
bool QXmlDefaultHandler::startDTD( const QString&, const QString&, const QString& )
2123
bool QXmlDefaultHandler::endDTD()
2133
bool QXmlDefaultHandler::startEntity( const QString& )
2143
bool QXmlDefaultHandler::endEntity( const QString& )
2153
bool QXmlDefaultHandler::startCDATA()
2163
bool QXmlDefaultHandler::endCDATA()
2173
bool QXmlDefaultHandler::comment( const QString& )
2183
bool QXmlDefaultHandler::attributeDecl( const QString&, const QString&, const QString&, const QString&, const QString& )
2193
bool QXmlDefaultHandler::internalEntityDecl( const QString&, const QString& )
2203
bool QXmlDefaultHandler::externalEntityDecl( const QString&, const QString&, const QString& )
2209
/*********************************************
2211
* QXmlSimpleReaderPrivate
2213
*********************************************/
2215
class QXmlSimpleReaderPrivate
2219
QXmlSimpleReaderPrivate()
2224
~QXmlSimpleReaderPrivate()
2229
void initIncrementalParsing()
2232
parseStack = new QPtrStack<ParseState>;
2233
parseStack->setAutoDelete( TRUE );
2236
// used to determine if elements are correctly nested
2237
QValueStack<QString> tags;
2239
// used for entity declarations
2240
struct ExternParameterEntity
2242
ExternParameterEntity( ) {}
2243
ExternParameterEntity( const QString &p, const QString &s )
2244
: publicId(p), systemId(s) {}
2248
Q_DUMMY_COMPARISON_OPERATOR(ExternParameterEntity)
2253
ExternEntity( const QString &p, const QString &s, const QString &n )
2254
: publicId(p), systemId(s), notation(n) {}
2258
Q_DUMMY_COMPARISON_OPERATOR(ExternEntity)
2260
QMap<QString,ExternParameterEntity> externParameterEntities;
2261
QMap<QString,QString> parameterEntities;
2262
QMap<QString,ExternEntity> externEntities;
2263
QMap<QString,QString> entities;
2265
// used for parsing of entity references
2266
QValueStack<QString> xmlRef;
2267
QValueStack<QString> xmlRefName;
2269
// used for standalone declaration
2270
enum Standalone { Yes, No, Unknown };
2272
QString doctype; // only used for the doctype
2273
QString xmlVersion; // only used to store the version information
2274
QString encoding; // only used to store the encoding
2275
Standalone standalone; // used to store the value of the standalone declaration
2277
QString publicId; // used by parseExternalID() to store the public ID
2278
QString systemId; // used by parseExternalID() to store the system ID
2279
QString attDeclEName; // use by parseAttlistDecl()
2280
QString attDeclAName; // use by parseAttlistDecl()
2282
// flags for some features support
2284
bool useNamespacePrefixes;
2285
bool reportWhitespaceCharData;
2286
bool reportEntities;
2288
// used to build the attribute list
2289
QXmlAttributes attList;
2291
// used in QXmlSimpleReader::parseContent() to decide whether character
2293
bool contentCharDataRead;
2296
QXmlLocator *locator;
2297
QXmlNamespaceSupport namespaceSupport;
2302
// arguments for parse functions (this is needed to allow incremental
2304
bool parsePI_xmldecl;
2305
bool parseName_useRef;
2306
bool parseReference_charDataRead;
2307
QXmlSimpleReader::EntityRecognitionContext parseReference_context;
2308
bool parseExternalID_allowPublicID;
2309
QXmlSimpleReader::EntityRecognitionContext parsePEReference_context;
2310
QString parseString_s;
2312
// for incremental parsing
2314
typedef bool (QXmlSimpleReader::*ParseFunction) ();
2315
ParseFunction function;
2318
QPtrStack<ParseState> *parseStack;
2320
// used in parseProlog()
2321
bool xmldecl_possible;
2324
// used in parseDoctype()
2325
bool startDTDwasReported;
2327
// used in parseString()
2331
// friend declarations
2332
friend class QXmlSimpleReader;
2336
/*********************************************
2340
*********************************************/
2343
\class QXmlReader qxml.h
2345
\brief The QXmlReader class provides an interface for XML readers (i.e.
2347
\if defined(commercial)
2348
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
2354
This abstract class provides an interface for all of Qt's XML
2355
readers. Currently there is only one implementation of a reader
2356
included in Qt's XML module: QXmlSimpleReader. In future releases
2357
there might be more readers with different properties available
2358
(e.g. a validating parser).
2360
The design of the XML classes follows the \link
2361
http://www.saxproject.org/ SAX2 Java interface\endlink, with
2362
the names adapted to fit Qt naming conventions. It should be very
2363
easy for anybody who has worked with SAX2 to get started with the
2366
All readers use the class QXmlInputSource to read the input
2367
document. Since you are normally interested in particular content
2368
in the XML document, the reader reports the content through
2369
special handler classes (QXmlDTDHandler, QXmlDeclHandler,
2370
QXmlContentHandler, QXmlEntityResolver, QXmlErrorHandler and
2371
QXmlLexicalHandler), which you must subclass, if you want to
2372
process the contents.
2374
Since the handler classes only describe interfaces you must
2375
implement all the functions. We provide the QXmlDefaultHandler
2376
class to make this easier: it implements a default behaviour (do
2377
nothing) for all functions, so you can subclass it and just
2378
implement the functions you are interested in.
2380
Features and properties of the reader can be set with setFeature()
2381
and setProperty() respectively. You can set the reader to use your
2382
own subclasses with setEntityResolver(), setDTDHandler(),
2383
setContentHandler(), setErrorHandler(), setLexicalHandler() and
2384
setDeclHandler(). The parse itself is started with a call to
2387
\sa QXmlSimpleReader
2391
\fn bool QXmlReader::feature( const QString& name, bool *ok ) const
2393
If the reader has the feature called \a name, the feature's value
2394
is returned. If no such feature exists the return value is
2397
If \a ok is not 0: \a *ok is set to TRUE if the reader has the
2398
feature called \a name; otherwise \a *ok is set to FALSE.
2400
\sa setFeature() hasFeature()
2404
\fn void QXmlReader::setFeature( const QString& name, bool value )
2406
Sets the feature called \a name to the given \a value. If the
2407
reader doesn't have the feature nothing happens.
2409
\sa feature() hasFeature()
2413
\fn bool QXmlReader::hasFeature( const QString& name ) const
2415
Returns \c TRUE if the reader has the feature called \a name;
2416
otherwise returns FALSE.
2418
\sa feature() setFeature()
2422
\fn void* QXmlReader::property( const QString& name, bool *ok ) const
2424
If the reader has the property \a name, this function returns the
2425
value of the property; otherwise the return value is undefined.
2427
If \a ok is not 0: if the reader has the \a name property \a *ok
2428
is set to TRUE; otherwise \a *ok is set to FALSE.
2430
\sa setProperty() hasProperty()
2434
\fn void QXmlReader::setProperty( const QString& name, void* value )
2436
Sets the property \a name to \a value. If the reader doesn't have
2437
the property nothing happens.
2439
\sa property() hasProperty()
2443
\fn bool QXmlReader::hasProperty( const QString& name ) const
2445
Returns TRUE if the reader has the property \a name; otherwise
2448
\sa property() setProperty()
2452
\fn void QXmlReader::setEntityResolver( QXmlEntityResolver* handler )
2454
Sets the entity resolver to \a handler.
2456
\sa entityResolver()
2460
\fn QXmlEntityResolver* QXmlReader::entityResolver() const
2462
Returns the entity resolver or 0 if none was set.
2464
\sa setEntityResolver()
2468
\fn void QXmlReader::setDTDHandler( QXmlDTDHandler* handler )
2470
Sets the DTD handler to \a handler.
2476
\fn QXmlDTDHandler* QXmlReader::DTDHandler() const
2478
Returns the DTD handler or 0 if none was set.
2484
\fn void QXmlReader::setContentHandler( QXmlContentHandler* handler )
2486
Sets the content handler to \a handler.
2488
\sa contentHandler()
2492
\fn QXmlContentHandler* QXmlReader::contentHandler() const
2494
Returns the content handler or 0 if none was set.
2496
\sa setContentHandler()
2500
\fn void QXmlReader::setErrorHandler( QXmlErrorHandler* handler )
2502
Sets the error handler to \a handler. Clears the error handler if
2509
\fn QXmlErrorHandler* QXmlReader::errorHandler() const
2511
Returns the error handler or 0 if none is set.
2513
\sa setErrorHandler()
2517
\fn void QXmlReader::setLexicalHandler( QXmlLexicalHandler* handler )
2519
Sets the lexical handler to \a handler.
2521
\sa lexicalHandler()
2525
\fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
2527
Returns the lexical handler or 0 if none was set.
2529
\sa setLexicalHandler()
2533
\fn void QXmlReader::setDeclHandler( QXmlDeclHandler* handler )
2535
Sets the declaration handler to \a handler.
2541
\fn QXmlDeclHandler* QXmlReader::declHandler() const
2543
Returns the declaration handler or 0 if none was set.
2545
\sa setDeclHandler()
2549
\fn bool QXmlReader::parse( const QXmlInputSource& input )
2555
\fn bool QXmlReader::parse( const QXmlInputSource* input )
2557
Reads an XML document from \a input and parses it. Returns TRUE if
2558
the parsing was successful; otherwise returns FALSE.
2563
\class QXmlSimpleReader qxml.h
2565
\brief The QXmlSimpleReader class provides an implementation of a
2566
simple XML reader (parser).
2567
\if defined(commercial)
2568
It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
2575
This XML reader is sufficient for simple parsing tasks. The reader:
2577
\i provides a well-formed parser;
2578
\i does not parse any external entities;
2579
\i can do namespace processing.
2582
Documents are parsed with a call to parse().
2588
Constructs a simple XML reader with the following feature settings:
2590
\header \i Feature \i Setting
2591
\row \i \e http://xml.org/sax/features/namespaces \i TRUE
2592
\row \i \e http://xml.org/sax/features/namespace-prefixes \i FALSE
2593
\row \i \e http://trolltech.com/xml/features/report-whitespace-only-CharData
2595
\row \i \e http://trolltech.com/xml/features/report-start-end-entity \i FALSE
2598
More information about features can be found in the \link
2599
xml.html#sax2Features Qt SAX2 overview. \endlink
2603
QXmlSimpleReader::QXmlSimpleReader()
2605
d = new QXmlSimpleReaderPrivate();
2606
d->locator = new QXmlSimpleReaderLocator( this );
2615
// default feature settings
2616
d->useNamespaces = TRUE;
2617
d->useNamespacePrefixes = FALSE;
2618
d->reportWhitespaceCharData = TRUE;
2619
d->reportEntities = FALSE;
2623
Destroys the simple XML reader.
2625
QXmlSimpleReader::~QXmlSimpleReader()
2634
bool QXmlSimpleReader::feature( const QString& name, bool *ok ) const
2638
if ( name == "http://xml.org/sax/features/namespaces" ) {
2639
return d->useNamespaces;
2640
} else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
2641
return d->useNamespacePrefixes;
2642
} else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
2643
return d->reportWhitespaceCharData;
2644
} else if ( name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
2645
return d->reportEntities;
2647
qWarning( "Unknown feature %s", name.latin1() );
2655
Sets the state of the feature \a name to \a value:
2657
If the feature is not recognized, it is ignored.
2659
The following features are supported:
2661
\header \i Feature \i Notes
2662
\row \i \e http://xml.org/sax/features/namespaces
2663
\i If this feature is TRUE, namespace processing is
2665
\row \i \e http://xml.org/sax/features/namespace-prefixes
2666
\i If this feature is TRUE, the the original prefixed names
2667
and attributes used for namespace declarations are
2669
\row \i \e http://trolltech.com/xml/features/report-whitespace-only-CharData
2670
\i If this feature is TRUE, CharData that consist of
2671
whitespace only (and no other characters) are not reported
2672
via QXmlContentHandler::characters().
2673
\row \i \e http://trolltech.com/xml/features/report-start-end-entity
2674
\i If this feature is TRUE, the parser reports
2675
QXmlContentHandler::startEntity() and
2676
QXmlContentHandler::endEntity() events. So character data
2677
might be reported in chunks. If this feature is FALSE, the
2678
parser does not report those events, but rather silently
2679
substitutes the entities and reports the character data in
2683
\quotefile xml/tagreader-with-features/tagreader.cpp
2687
\printline setFeature
2690
(Code taken from xml/tagreader-with-features/tagreader.cpp)
2692
\sa feature() hasFeature()
2694
void QXmlSimpleReader::setFeature( const QString& name, bool value )
2696
if ( name == "http://xml.org/sax/features/namespaces" ) {
2697
d->useNamespaces = value;
2698
} else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
2699
d->useNamespacePrefixes = value;
2700
} else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
2701
d->reportWhitespaceCharData = value;
2702
} else if ( name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
2703
d->reportEntities = value;
2705
qWarning( "Unknown feature %s", name.latin1() );
2711
bool QXmlSimpleReader::hasFeature( const QString& name ) const
2713
if ( name == "http://xml.org/sax/features/namespaces"
2714
|| name == "http://xml.org/sax/features/namespace-prefixes"
2715
|| name == "http://trolltech.com/xml/features/report-whitespace-only-CharData"
2716
|| name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
2725
void* QXmlSimpleReader::property( const QString&, bool *ok ) const
2734
void QXmlSimpleReader::setProperty( const QString&, void* )
2741
bool QXmlSimpleReader::hasProperty( const QString& ) const
2749
void QXmlSimpleReader::setEntityResolver( QXmlEntityResolver* handler )
2750
{ entityRes = handler; }
2755
QXmlEntityResolver* QXmlSimpleReader::entityResolver() const
2756
{ return entityRes; }
2761
void QXmlSimpleReader::setDTDHandler( QXmlDTDHandler* handler )
2762
{ dtdHnd = handler; }
2767
QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const
2773
void QXmlSimpleReader::setContentHandler( QXmlContentHandler* handler )
2774
{ contentHnd = handler; }
2779
QXmlContentHandler* QXmlSimpleReader::contentHandler() const
2780
{ return contentHnd; }
2785
void QXmlSimpleReader::setErrorHandler( QXmlErrorHandler* handler )
2786
{ errorHnd = handler; }
2791
QXmlErrorHandler* QXmlSimpleReader::errorHandler() const
2792
{ return errorHnd; }
2797
void QXmlSimpleReader::setLexicalHandler( QXmlLexicalHandler* handler )
2798
{ lexicalHnd = handler; }
2803
QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const
2804
{ return lexicalHnd; }
2809
void QXmlSimpleReader::setDeclHandler( QXmlDeclHandler* handler )
2810
{ declHnd = handler; }
2815
QXmlDeclHandler* QXmlSimpleReader::declHandler() const
2823
bool QXmlSimpleReader::parse( const QXmlInputSource& input )
2825
return parse( &input, FALSE );
2831
bool QXmlSimpleReader::parse( const QXmlInputSource* input )
2833
return parse( input, FALSE );
2837
Reads an XML document from \a input and parses it. Returns FALSE
2838
if the parsing detects an error; otherwise returns TRUE.
2840
If \a incremental is TRUE, the parser does not return FALSE when
2841
it reaches the end of the \a input without reaching the end of the
2842
XML file. Instead it stores the state of the parser so that
2843
parsing can be continued at a later stage when more data is
2844
available. You can use the function parseContinue() to continue
2845
with parsing. This class stores a pointer to the input source \a
2846
input and the parseContinue() function tries to read from that
2847
input souce. This means that you should not delete the input
2848
source \a input until you've finished your calls to
2849
parseContinue(). If you call this function with \a incremental
2850
TRUE whilst an incremental parse is in progress a new parsing
2851
session will be started and the previous session lost.
2853
If \a incremental is FALSE, this function behaves like the normal
2854
parse function, i.e. it returns FALSE when the end of input is
2855
reached without reaching the end of the XML file and the parsing
2856
cannot be continued.
2858
\sa parseContinue() QSocket
2860
bool QXmlSimpleReader::parse( const QXmlInputSource *input, bool incremental )
2863
if ( incremental ) {
2864
d->initIncrementalParsing();
2866
delete d->parseStack;
2871
contentHnd->setDocumentLocator( d->locator );
2872
if ( !contentHnd->startDocument() ) {
2873
reportParseError( contentHnd->errorString() );
2878
return parseBeginOrContinue( 0, incremental );
2882
Continues incremental parsing; this function reads the input from
2883
the QXmlInputSource that was specified with the last parse()
2884
command. To use this function, you \e must have called parse()
2885
with the incremental argument set to TRUE.
2887
Returns FALSE if a parsing error occurs; otherwise returns TRUE.
2889
If the input source returns an empty string for the function
2890
QXmlInputSource::data(), then this means that the end of the XML
2891
file has been reached; this is quite important, especially if you
2892
want to use the reader to parse more than one XML file.
2894
The case of the end of the XML file being reached without having
2895
finished parsing is not considered to be an error: you can
2896
continue parsing at a later stage by calling this function again
2897
when there is more data available to parse.
2899
This function assumes that the end of the XML document is reached
2900
if the QXmlInputSource::next() function returns
2901
QXmlInputSource::EndOfDocument. If the parser has not finished
2902
parsing when it encounters this symbol, it is an error and FALSE
2905
\sa parse() QXmlInputSource::next()
2907
bool QXmlSimpleReader::parseContinue()
2909
if ( d->parseStack == 0 )
2911
if ( d->parseStack->isEmpty() )
2914
int state = state = d->parseStack->top()->state;
2915
d->parseStack->remove();
2916
return parseBeginOrContinue( state, TRUE );
2920
Common part of parse() and parseContinue()
2922
bool QXmlSimpleReader::parseBeginOrContinue( int state, bool incremental )
2924
bool atEndOrig = atEnd();
2927
if ( !parseProlog() ) {
2928
if ( incremental && d->error.isNull() ) {
2929
pushParseState( 0, 0 );
2939
if ( !parseElement() ) {
2940
if ( incremental && d->error.isNull() ) {
2941
pushParseState( 0, 1 );
2951
while ( !atEnd() ) {
2952
if ( !parseMisc() ) {
2953
if ( incremental && d->error.isNull() ) {
2954
pushParseState( 0, 2 );
2962
if ( !atEndOrig && incremental ) {
2963
// we parsed something at all, so be prepared to come back later
2964
pushParseState( 0, 2 );
2968
if ( !d->tags.isEmpty() && !d->error.isNull() ) {
2969
reportParseError( XMLERR_UNEXPECTEDEOF );
2975
delete d->parseStack;
2977
if ( !contentHnd->endDocument() ) {
2978
reportParseError( contentHnd->errorString() );
2986
// The following private parse functions have another semantics for the return
2987
// value: They return TRUE iff parsing has finished successfully (i.e. the end
2988
// of the XML file must be reached!). If one of these functions return FALSE,
2989
// there is only an error when d->error.isNULL() is also FALSE.
2993
For the incremental parsing, it is very important that the parse...()
2994
functions have a certain structure. Since it might be hard to understand how
2995
they work, here is a description of the layout of these functions:
2997
bool QXmlSimpleReader::parse...()
2999
(1) const signed char Init = 0;
3002
(2) const signed char Inp... = 0;
3005
(3) static signed char table[3][2] = {
3011
(4) if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
3018
(5) switch ( state ) {
3023
(6a) if ( atEnd() ) {
3024
unexpectedEof( &QXmlSimpleReader::parseNmtoken, state );
3027
(6b) if ( is_NameChar(c) ) {
3030
(7) state = table[state][input];
3032
(8) switch ( state ) {
3039
ad 1: constants for the states (used in the transition table)
3040
ad 2: constants for the input (used in the transition table)
3041
ad 3: the transition table for the state machine
3042
ad 4: test if we are in a parseContinue() step
3043
a) if no, do inititalizations
3044
b) if yes, restore the state and call parse functions recursively
3045
ad 5: Do some actions according to the state; from the logical execution
3046
order, this code belongs after 8 (see there for an explanation)
3047
ad 6: Check the character that is at the actual "cursor" position:
3048
a) If we reached the EOF, report either error or push the state (in the
3049
case of incremental parsing).
3050
b) Otherwise, set the input character constant for the transition
3052
ad 7: Get the new state according to the input that was read.
3053
ad 8: Do some actions according to the state. The last line in every case
3054
statement reads new data (i.e. it move the cursor). This can also be
3055
done by calling another parse...() funtion. If you need processing for
3056
this state after that, you have to put it into the switch statement 5.
3057
This ensures that you have a well defined re-entry point, when you ran
3062
Parses the prolog [22].
3064
bool QXmlSimpleReader::parseProlog()
3066
const signed char Init = 0;
3067
const signed char EatWS = 1; // eat white spaces
3068
const signed char Lt = 2; // '<' read
3069
const signed char Em = 3; // '!' read
3070
const signed char DocType = 4; // read doctype
3071
const signed char Comment = 5; // read comment
3072
const signed char CommentR = 6; // same as Comment, but already reported
3073
const signed char PInstr = 7; // read PI
3074
const signed char PInstrR = 8; // same as PInstr, but already reported
3075
const signed char Done = 9;
3077
const signed char InpWs = 0;
3078
const signed char InpLt = 1; // <
3079
const signed char InpQm = 2; // ?
3080
const signed char InpEm = 3; // !
3081
const signed char InpD = 4; // D
3082
const signed char InpDash = 5; // -
3083
const signed char InpUnknown = 6;
3085
static const signed char table[9][7] = {
3086
/* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
3087
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
3088
{ -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
3089
{ -1, -1, PInstr,Em, Done, -1, Done }, // Lt
3090
{ -1, -1, -1, -1, DocType, Comment, -1 }, // Em
3091
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
3092
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
3093
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // CommentR
3094
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // PInstr
3095
{ EatWS, Lt, -1, -1, -1, -1, -1 } // PInstrR
3100
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
3101
d->xmldecl_possible = TRUE;
3102
d->doctype_read = FALSE;
3105
state = d->parseStack->top()->state;
3106
d->parseStack->remove();
3107
#if defined(QT_QXML_DEBUG)
3108
qDebug( "QXmlSimpleReader: parseProlog (cont) in state %d", state );
3110
if ( !d->parseStack->isEmpty() ) {
3111
ParseFunction function = d->parseStack->top()->function;
3112
if ( function == &QXmlSimpleReader::eat_ws ) {
3113
d->parseStack->remove();
3114
#if defined(QT_QXML_DEBUG)
3115
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
3118
if ( !(this->*function)() ) {
3119
parseFailed( &QXmlSimpleReader::parseProlog, state );
3128
if ( d->doctype_read ) {
3129
reportParseError( XMLERR_MORETHANONEDOCTYPE );
3132
d->doctype_read = FALSE;
3137
if ( !lexicalHnd->comment( string() ) ) {
3138
reportParseError( lexicalHnd->errorString() );
3147
if ( d->xmldecl_possible && !d->xmlVersion.isEmpty() ) {
3148
QString value( "version = '" );
3149
value += d->xmlVersion;
3151
if ( !d->encoding.isEmpty() ) {
3152
value += " encoding = '";
3153
value += d->encoding;
3156
if ( d->standalone == QXmlSimpleReaderPrivate::Yes ) {
3157
value += " standalone = 'yes'";
3158
} else if ( d->standalone == QXmlSimpleReaderPrivate::No ) {
3159
value += " standalone = 'no'";
3161
if ( !contentHnd->processingInstruction( "xml", value ) ) {
3162
reportParseError( contentHnd->errorString() );
3166
if ( !contentHnd->processingInstruction( name(), string() ) ) {
3167
reportParseError( contentHnd->errorString() );
3172
// XML declaration only on first position possible
3173
d->xmldecl_possible = FALSE;
3179
reportParseError( XMLERR_ERRORPARSINGELEMENT );
3184
unexpectedEof( &QXmlSimpleReader::parseProlog, state );
3189
} else if ( c == '<' ) {
3191
} else if ( c == '?' ) {
3193
} else if ( c == '!' ) {
3195
} else if ( c == 'D' ) {
3197
} else if ( c == '-' ) {
3202
state = table[state][input];
3206
// XML declaration only on first position possible
3207
d->xmldecl_possible = FALSE;
3209
parseFailed( &QXmlSimpleReader::parseProlog, state );
3217
// XML declaration only on first position possible
3218
d->xmldecl_possible = FALSE;
3222
if ( !parseDoctype() ) {
3223
parseFailed( &QXmlSimpleReader::parseProlog, state );
3229
if ( !parseComment() ) {
3230
parseFailed( &QXmlSimpleReader::parseProlog, state );
3236
d->parsePI_xmldecl = d->xmldecl_possible;
3238
parseFailed( &QXmlSimpleReader::parseProlog, state );
3247
Parse an element [39].
3249
Precondition: the opening '<' is already read.
3251
bool QXmlSimpleReader::parseElement()
3253
const signed char Init = 0;
3254
const signed char ReadName = 1;
3255
const signed char Ws1 = 2;
3256
const signed char STagEnd = 3;
3257
const signed char STagEnd2 = 4;
3258
const signed char ETagBegin = 5;
3259
const signed char ETagBegin2 = 6;
3260
const signed char Ws2 = 7;
3261
const signed char EmptyTag = 8;
3262
const signed char Attrib = 9;
3263
const signed char AttribPro = 10; // like Attrib, but processAttribute was already called
3264
const signed char Ws3 = 11;
3265
const signed char Done = 12;
3267
const signed char InpWs = 0; // whitespace
3268
const signed char InpNameBe = 1; // is_NameBeginning()
3269
const signed char InpGt = 2; // >
3270
const signed char InpSlash = 3; // /
3271
const signed char InpUnknown = 4;
3273
static const signed char table[12][5] = {
3274
/* InpWs InpNameBe InpGt InpSlash InpUnknown */
3275
{ -1, ReadName, -1, -1, -1 }, // Init
3276
{ Ws1, Attrib, STagEnd, EmptyTag, -1 }, // ReadName
3277
{ -1, Attrib, STagEnd, EmptyTag, -1 }, // Ws1
3278
{ STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
3279
{ -1, -1, -1, ETagBegin, -1 }, // STagEnd2
3280
{ -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
3281
{ Ws2, -1, Done, -1, -1 }, // ETagBegin2
3282
{ -1, -1, Done, -1, -1 }, // Ws2
3283
{ -1, -1, Done, -1, -1 }, // EmptyTag
3284
{ Ws3, Attrib, STagEnd, EmptyTag, -1 }, // Attrib
3285
{ Ws3, Attrib, STagEnd, EmptyTag, -1 }, // AttribPro
3286
{ -1, Attrib, STagEnd, EmptyTag, -1 } // Ws3
3291
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
3294
state = d->parseStack->top()->state;
3295
d->parseStack->remove();
3296
#if defined(QT_QXML_DEBUG)
3297
qDebug( "QXmlSimpleReader: parseElement (cont) in state %d", state );
3299
if ( !d->parseStack->isEmpty() ) {
3300
ParseFunction function = d->parseStack->top()->function;
3301
if ( function == &QXmlSimpleReader::eat_ws ) {
3302
d->parseStack->remove();
3303
#if defined(QT_QXML_DEBUG)
3304
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
3307
if ( !(this->*function)() ) {
3308
parseFailed( &QXmlSimpleReader::parseElement, state );
3317
// store it on the stack
3318
d->tags.push( name() );
3319
// empty the attributes
3321
if ( d->useNamespaces ) {
3322
d->namespaceSupport.pushContext();
3326
if ( !processElementETagBegin2() )
3330
if ( !processElementAttribute() )
3337
reportParseError( XMLERR_ERRORPARSINGELEMENT );
3342
unexpectedEof( &QXmlSimpleReader::parseElement, state );
3347
} else if ( is_NameBeginning(c) ) {
3349
} else if ( c == '>' ) {
3351
} else if ( c == '/' ) {
3356
state = table[state][input];
3360
d->parseName_useRef = FALSE;
3361
if ( !parseName() ) {
3362
parseFailed( &QXmlSimpleReader::parseElement, state );
3370
parseFailed( &QXmlSimpleReader::parseElement, state );
3377
if ( d->useNamespaces ) {
3379
d->namespaceSupport.processName( d->tags.top(), FALSE, uri, lname );
3380
if ( !contentHnd->startElement( uri, lname, d->tags.top(), d->attList ) ) {
3381
reportParseError( contentHnd->errorString() );
3385
if ( !contentHnd->startElement( QString::null, QString::null, d->tags.top(), d->attList ) ) {
3386
reportParseError( contentHnd->errorString() );
3394
if ( !parseContent() ) {
3395
parseFailed( &QXmlSimpleReader::parseElement, state );
3403
// get the name of the tag
3404
d->parseName_useRef = FALSE;
3405
if ( !parseName() ) {
3406
parseFailed( &QXmlSimpleReader::parseElement, state );
3411
if ( d->tags.isEmpty() ) {
3412
reportParseError( XMLERR_TAGMISMATCH );
3415
if ( !processElementEmptyTag() )
3421
// get name and value of attribute
3422
if ( !parseAttribute() ) {
3423
parseFailed( &QXmlSimpleReader::parseElement, state );
3434
Helper to break down the size of the code in the case statement.
3435
Return FALSE on error, otherwise TRUE.
3437
bool QXmlSimpleReader::processElementEmptyTag()
3440
// pop the stack and call the handler
3442
if ( d->useNamespaces ) {
3443
// report startElement first...
3444
d->namespaceSupport.processName( d->tags.top(), FALSE, uri, lname );
3445
if ( !contentHnd->startElement( uri, lname, d->tags.top(), d->attList ) ) {
3446
reportParseError( contentHnd->errorString() );
3449
// ... followed by endElement...
3450
if ( !contentHnd->endElement( uri, lname, d->tags.pop() ) ) {
3451
reportParseError( contentHnd->errorString() );
3454
// ... followed by endPrefixMapping
3455
QStringList prefixesBefore, prefixesAfter;
3457
prefixesBefore = d->namespaceSupport.prefixes();
3459
d->namespaceSupport.popContext();
3460
// call the handler for prefix mapping
3461
prefixesAfter = d->namespaceSupport.prefixes();
3462
for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
3463
if ( prefixesAfter.contains(*it) == 0 ) {
3464
if ( !contentHnd->endPrefixMapping( *it ) ) {
3465
reportParseError( contentHnd->errorString() );
3471
// report startElement first...
3472
if ( !contentHnd->startElement( QString::null, QString::null, d->tags.top(), d->attList ) ) {
3473
reportParseError( contentHnd->errorString() );
3476
// ... followed by endElement
3477
if ( !contentHnd->endElement( QString::null, QString::null, d->tags.pop() ) ) {
3478
reportParseError( contentHnd->errorString() );
3484
d->namespaceSupport.popContext();
3489
Helper to break down the size of the code in the case statement.
3490
Return FALSE on error, otherwise TRUE.
3492
bool QXmlSimpleReader::processElementETagBegin2()
3494
// pop the stack and compare it with the name
3495
if ( d->tags.pop() != name() ) {
3496
reportParseError( XMLERR_TAGMISMATCH );
3501
if ( d->useNamespaces ) {
3503
d->namespaceSupport.processName( name(), FALSE, uri, lname );
3504
if ( !contentHnd->endElement( uri, lname, name() ) ) {
3505
reportParseError( contentHnd->errorString() );
3509
if ( !contentHnd->endElement( QString::null, QString::null, name() ) ) {
3510
reportParseError( contentHnd->errorString() );
3515
if ( d->useNamespaces ) {
3516
QStringList prefixesBefore, prefixesAfter;
3518
prefixesBefore = d->namespaceSupport.prefixes();
3520
d->namespaceSupport.popContext();
3521
// call the handler for prefix mapping
3523
prefixesAfter = d->namespaceSupport.prefixes();
3524
for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
3525
if ( prefixesAfter.contains(*it) == 0 ) {
3526
if ( !contentHnd->endPrefixMapping( *it ) ) {
3527
reportParseError( contentHnd->errorString() );
3537
Helper to break down the size of the code in the case statement.
3538
Return FALSE on error, otherwise TRUE.
3540
bool QXmlSimpleReader::processElementAttribute()
3542
QString uri, lname, prefix;
3543
// add the attribute to the list
3544
if ( d->useNamespaces ) {
3545
// is it a namespace declaration?
3546
d->namespaceSupport.splitName( name(), prefix, lname );
3547
if ( prefix == "xmlns" ) {
3548
// namespace declaration
3549
d->namespaceSupport.setPrefix( lname, string() );
3550
if ( d->useNamespacePrefixes ) {
3551
// according to http://www.w3.org/2000/xmlns/, the "prefix"
3552
// xmlns maps to the namespace name
3553
// http://www.w3.org/2000/xmlns/
3554
d->attList.append( name(), "http://www.w3.org/2000/xmlns/", lname, string() );
3556
// call the handler for prefix mapping
3558
if ( !contentHnd->startPrefixMapping( lname, string() ) ) {
3559
reportParseError( contentHnd->errorString() );
3564
// no namespace delcaration
3565
d->namespaceSupport.processName( name(), TRUE, uri, lname );
3566
d->attList.append( name(), uri, lname, string() );
3569
// no namespace support
3570
d->attList.append( name(), QString::null, QString::null, string() );
3576
Parse a content [43].
3578
A content is only used between tags. If a end tag is found the < is already
3579
read and the head stand on the '/' of the end tag '</name>'.
3581
bool QXmlSimpleReader::parseContent()
3583
const signed char Init = 0;
3584
const signed char ChD = 1; // CharData
3585
const signed char ChD1 = 2; // CharData help state
3586
const signed char ChD2 = 3; // CharData help state
3587
const signed char Ref = 4; // Reference
3588
const signed char Lt = 5; // '<' read
3589
const signed char PInstr = 6; // PI
3590
const signed char PInstrR = 7; // same as PInstr, but already reported
3591
const signed char Elem = 8; // Element
3592
const signed char Em = 9; // '!' read
3593
const signed char Com = 10; // Comment
3594
const signed char ComR = 11; // same as Com, but already reported
3595
const signed char CDS = 12; // CDSect
3596
const signed char CDS1 = 13; // read a CDSect
3597
const signed char CDS2 = 14; // read a CDSect (help state)
3598
const signed char CDS3 = 15; // read a CDSect (help state)
3599
const signed char Done = 16; // finished reading content
3601
const signed char InpLt = 0; // <
3602
const signed char InpGt = 1; // >
3603
const signed char InpSlash = 2; // /
3604
const signed char InpQMark = 3; // ?
3605
const signed char InpEMark = 4; // !
3606
const signed char InpAmp = 5; // &
3607
const signed char InpDash = 6; // -
3608
const signed char InpOpenB = 7; // [
3609
const signed char InpCloseB = 8; // ]
3610
const signed char InpUnknown = 9;
3612
static const signed char mapCLT2FSMChar[] = {
3613
InpUnknown, // white space
3627
InpUnknown // unknown
3630
static const signed char table[16][10] = {
3631
/* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
3632
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
3633
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
3634
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
3635
{ Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
3636
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
3637
{ -1, -1, Done, PInstr, Em, -1, -1, -1, -1, Elem }, // Lt
3638
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstr (same as Init)
3639
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstrR
3640
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
3641
{ -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
3642
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
3643
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // ComR
3644
{ CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
3645
{ CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
3646
{ CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
3647
{ CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
3652
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
3653
d->contentCharDataRead = FALSE;
3656
state = d->parseStack->top()->state;
3657
d->parseStack->remove();
3658
#if defined(QT_QXML_DEBUG)
3659
qDebug( "QXmlSimpleReader: parseContent (cont) in state %d", state );
3661
if ( !d->parseStack->isEmpty() ) {
3662
ParseFunction function = d->parseStack->top()->function;
3663
if ( function == &QXmlSimpleReader::eat_ws ) {
3664
d->parseStack->remove();
3665
#if defined(QT_QXML_DEBUG)
3666
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
3669
if ( !(this->*function)() ) {
3670
parseFailed( &QXmlSimpleReader::parseContent, state );
3679
if ( !d->contentCharDataRead)
3680
d->contentCharDataRead = d->parseReference_charDataRead;
3684
if ( !contentHnd->processingInstruction(name(),string()) ) {
3685
reportParseError( contentHnd->errorString() );
3693
if ( !lexicalHnd->comment( string() ) ) {
3694
reportParseError( lexicalHnd->errorString() );
3704
if ( !atEnd() && c != ']' )
3708
// test if this skipping was legal
3711
// the end of the CDSect
3713
if ( !lexicalHnd->startCDATA() ) {
3714
reportParseError( lexicalHnd->errorString() );
3719
if ( !contentHnd->characters( string() ) ) {
3720
reportParseError( contentHnd->errorString() );
3725
if ( !lexicalHnd->endCDATA() ) {
3726
reportParseError( lexicalHnd->errorString() );
3730
} else if (c == ']') {
3731
// three or more ']'
3734
// after ']]' comes another character
3741
// call the handler for CharData
3743
if ( d->contentCharDataRead ) {
3744
if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
3745
if ( !contentHnd->characters( string() ) ) {
3746
reportParseError( contentHnd->errorString() );
3756
reportParseError( XMLERR_ERRORPARSINGCONTENT );
3760
// get input (use lookup-table instead of nested ifs for performance
3763
unexpectedEof( &QXmlSimpleReader::parseContent, state );
3769
input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ];
3771
state = table[state][input];
3775
// skip the ending '>' of a CDATASection
3779
// on first call: clear string
3780
if ( !d->contentCharDataRead ) {
3781
d->contentCharDataRead = TRUE;
3785
if ( d->reportEntities ) {
3786
if ( !reportEndEntities() )
3792
// on first call: clear string
3793
if ( !d->contentCharDataRead ) {
3794
d->contentCharDataRead = TRUE;
3798
if ( d->reportEntities ) {
3799
if ( !reportEndEntities() )
3806
if ( d->reportEntities ) {
3807
if ( !reportEndEntities() )
3813
if ( !d->contentCharDataRead) {
3814
// reference may be CharData; so clear string to be safe
3816
d->parseReference_context = InContent;
3817
if ( !parseReference() ) {
3818
parseFailed( &QXmlSimpleReader::parseContent, state );
3822
if ( d->reportEntities ) {
3823
// report character data in chunks
3825
if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
3826
if ( !contentHnd->characters( string() ) ) {
3827
reportParseError( contentHnd->errorString() );
3834
d->parseReference_context = InContent;
3835
if ( !parseReference() ) {
3836
parseFailed( &QXmlSimpleReader::parseContent, state );
3842
// call the handler for CharData
3844
if ( d->contentCharDataRead ) {
3845
if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
3846
if ( !contentHnd->characters( string() ) ) {
3847
reportParseError( contentHnd->errorString() );
3853
d->contentCharDataRead = FALSE;
3858
d->parsePI_xmldecl = FALSE;
3860
parseFailed( &QXmlSimpleReader::parseContent, state );
3865
if ( !parseElement() ) {
3866
parseFailed( &QXmlSimpleReader::parseContent, state );
3875
if ( !parseComment() ) {
3876
parseFailed( &QXmlSimpleReader::parseContent, state );
3881
d->parseString_s = "[CDATA[";
3882
if ( !parseString() ) {
3883
parseFailed( &QXmlSimpleReader::parseContent, state );
3902
bool QXmlSimpleReader::reportEndEntities()
3904
int count = (int)d->xmlRef.count();
3905
while ( count != 0 && d->xmlRef.top().isEmpty() ) {
3907
if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
3908
if ( !contentHnd->characters( string() ) ) {
3909
reportParseError( contentHnd->errorString() );
3916
if ( !lexicalHnd->endEntity(d->xmlRefName.top()) ) {
3917
reportParseError( lexicalHnd->errorString() );
3921
d->xmlRef.pop_back();
3922
d->xmlRefName.pop_back();
3931
bool QXmlSimpleReader::parseMisc()
3933
const signed char Init = 0;
3934
const signed char Lt = 1; // '<' was read
3935
const signed char Comment = 2; // read comment
3936
const signed char eatWS = 3; // eat whitespaces
3937
const signed char PInstr = 4; // read PI
3938
const signed char Comment2 = 5; // read comment
3940
const signed char InpWs = 0; // S
3941
const signed char InpLt = 1; // <
3942
const signed char InpQm = 2; // ?
3943
const signed char InpEm = 3; // !
3944
const signed char InpUnknown = 4;
3946
static const signed char table[3][5] = {
3947
/* InpWs InpLt InpQm InpEm InpUnknown */
3948
{ eatWS, Lt, -1, -1, -1 }, // Init
3949
{ -1, -1, PInstr,Comment, -1 }, // Lt
3950
{ -1, -1, -1, -1, Comment2 } // Comment
3955
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
3958
state = d->parseStack->top()->state;
3959
d->parseStack->remove();
3960
#if defined(QT_QXML_DEBUG)
3961
qDebug( "QXmlSimpleReader: parseMisc (cont) in state %d", state );
3963
if ( !d->parseStack->isEmpty() ) {
3964
ParseFunction function = d->parseStack->top()->function;
3965
if ( function == &QXmlSimpleReader::eat_ws ) {
3966
d->parseStack->remove();
3967
#if defined(QT_QXML_DEBUG)
3968
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
3971
if ( !(this->*function)() ) {
3972
parseFailed( &QXmlSimpleReader::parseMisc, state );
3984
if ( !contentHnd->processingInstruction(name(),string()) ) {
3985
reportParseError( contentHnd->errorString() );
3992
if ( !lexicalHnd->comment( string() ) ) {
3993
reportParseError( lexicalHnd->errorString() );
4000
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
4005
unexpectedEof( &QXmlSimpleReader::parseMisc, state );
4010
} else if ( c == '<' ) {
4012
} else if ( c == '?' ) {
4014
} else if ( c == '!' ) {
4019
state = table[state][input];
4024
parseFailed( &QXmlSimpleReader::parseMisc, state );
4032
d->parsePI_xmldecl = FALSE;
4034
parseFailed( &QXmlSimpleReader::parseMisc, state );
4042
if ( !parseComment() ) {
4043
parseFailed( &QXmlSimpleReader::parseMisc, state );
4052
Parse a processing instruction [16].
4054
If xmldec is TRUE, it tries to parse a PI or a XML declaration [23].
4056
Precondition: the beginning '<' of the PI is already read and the head stand
4059
If this funktion was successful, the head-position is on the first
4060
character after the PI.
4062
bool QXmlSimpleReader::parsePI()
4064
const signed char Init = 0;
4065
const signed char QmI = 1; // ? was read
4066
const signed char Name = 2; // read Name
4067
const signed char XMLDecl = 3; // read XMLDecl
4068
const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
4069
const signed char PInstr = 5; // read PI
4070
const signed char Ws2 = 6; // eat ws after Name of PI
4071
const signed char Version = 7; // read versionInfo
4072
const signed char Ws3 = 8; // eat ws after versionInfo
4073
const signed char EorSD = 9; // read EDecl or SDDecl
4074
const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
4075
const signed char SD = 11; // read SDDecl
4076
const signed char Ws5 = 12; // eat ws after SDDecl
4077
const signed char ADone = 13; // almost done
4078
const signed char Char = 14; // Char was read
4079
const signed char Qm = 15; // Qm was read
4080
const signed char Done = 16; // finished reading content
4082
const signed char InpWs = 0; // whitespace
4083
const signed char InpNameBe = 1; // is_nameBeginning()
4084
const signed char InpGt = 2; // >
4085
const signed char InpQm = 3; // ?
4086
const signed char InpUnknown = 4;
4088
static const signed char table[16][5] = {
4089
/* InpWs, InpNameBe InpGt InpQm InpUnknown */
4090
{ -1, -1, -1, QmI, -1 }, // Init
4091
{ -1, Name, -1, -1, -1 }, // QmI
4092
{ -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
4093
{ Ws1, -1, -1, -1, -1 }, // XMLDecl
4094
{ -1, Version, -1, -1, -1 }, // Ws1
4095
{ Ws2, -1, -1, Qm, -1 }, // PInstr
4096
{ Char, Char, Char, Qm, Char }, // Ws2
4097
{ Ws3, -1, -1, ADone, -1 }, // Version
4098
{ -1, EorSD, -1, ADone, -1 }, // Ws3
4099
{ Ws4, -1, -1, ADone, -1 }, // EorSD
4100
{ -1, SD, -1, ADone, -1 }, // Ws4
4101
{ Ws5, -1, -1, ADone, -1 }, // SD
4102
{ -1, -1, -1, ADone, -1 }, // Ws5
4103
{ -1, -1, Done, -1, -1 }, // ADone
4104
{ Char, Char, Char, Qm, Char }, // Char
4105
{ Char, Char, Done, Qm, Char }, // Qm
4110
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
4113
state = d->parseStack->top()->state;
4114
d->parseStack->remove();
4115
#if defined(QT_QXML_DEBUG)
4116
qDebug( "QXmlSimpleReader: parsePI (cont) in state %d", state );
4118
if ( !d->parseStack->isEmpty() ) {
4119
ParseFunction function = d->parseStack->top()->function;
4120
if ( function == &QXmlSimpleReader::eat_ws ) {
4121
d->parseStack->remove();
4122
#if defined(QT_QXML_DEBUG)
4123
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
4126
if ( !(this->*function)() ) {
4127
parseFailed( &QXmlSimpleReader::parsePI, state );
4136
// test what name was read and determine the next state
4137
// (not very beautiful, I admit)
4138
if ( name().lower() == "xml" ) {
4139
if ( d->parsePI_xmldecl && name()=="xml" ) {
4142
reportParseError( XMLERR_INVALIDNAMEFORPI );
4151
// get version (syntax like an attribute)
4152
if ( name() != "version" ) {
4153
reportParseError( XMLERR_VERSIONEXPECTED );
4156
d->xmlVersion = string();
4159
// get the EDecl or SDDecl (syntax like an attribute)
4160
if ( name() == "standalone" ) {
4161
if ( string()=="yes" ) {
4162
d->standalone = QXmlSimpleReaderPrivate::Yes;
4163
} else if ( string()=="no" ) {
4164
d->standalone = QXmlSimpleReaderPrivate::No;
4166
reportParseError( XMLERR_WRONGVALUEFORSDECL );
4169
} else if ( name() == "encoding" ) {
4170
d->encoding = string();
4172
reportParseError( XMLERR_EDECLORSDDECLEXPECTED );
4177
if ( name() != "standalone" ) {
4178
reportParseError( XMLERR_SDDECLEXPECTED );
4181
if ( string()=="yes" ) {
4182
d->standalone = QXmlSimpleReaderPrivate::Yes;
4183
} else if ( string()=="no" ) {
4184
d->standalone = QXmlSimpleReaderPrivate::No;
4186
reportParseError( XMLERR_WRONGVALUEFORSDECL );
4191
// test if the skipping was legal
4192
if ( !atEnd() && c != '>' )
4199
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
4204
unexpectedEof( &QXmlSimpleReader::parsePI, state );
4209
} else if ( is_NameBeginning(c) ) {
4211
} else if ( c == '>' ) {
4213
} else if ( c == '?' ) {
4218
state = table[state][input];
4225
d->parseName_useRef = FALSE;
4226
if ( !parseName() ) {
4227
parseFailed( &QXmlSimpleReader::parsePI, state );
4237
parseFailed( &QXmlSimpleReader::parsePI, state );
4242
if ( !parseAttribute() ) {
4243
parseFailed( &QXmlSimpleReader::parsePI, state );
4248
if ( !parseAttribute() ) {
4249
parseFailed( &QXmlSimpleReader::parsePI, state );
4254
// get the SDDecl (syntax like an attribute)
4255
if ( d->standalone != QXmlSimpleReaderPrivate::Unknown ) {
4256
// already parsed the standalone declaration
4257
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
4260
if ( !parseAttribute() ) {
4261
parseFailed( &QXmlSimpleReader::parsePI, state );
4284
Parse a document type definition (doctypedecl [28]).
4286
Precondition: the beginning '<!' of the doctype is already read the head
4287
stands on the 'D' of '<!DOCTYPE'.
4289
If this funktion was successful, the head-position is on the first
4290
character after the document type definition.
4292
bool QXmlSimpleReader::parseDoctype()
4294
const signed char Init = 0;
4295
const signed char Doctype = 1; // read the doctype
4296
const signed char Ws1 = 2; // eat_ws
4297
const signed char Doctype2 = 3; // read the doctype, part 2
4298
const signed char Ws2 = 4; // eat_ws
4299
const signed char Sys = 5; // read SYSTEM or PUBLIC
4300
const signed char Ws3 = 6; // eat_ws
4301
const signed char MP = 7; // markupdecl or PEReference
4302
const signed char MPR = 8; // same as MP, but already reported
4303
const signed char PER = 9; // PERReference
4304
const signed char Mup = 10; // markupdecl
4305
const signed char Ws4 = 11; // eat_ws
4306
const signed char MPE = 12; // end of markupdecl or PEReference
4307
const signed char Done = 13;
4309
const signed char InpWs = 0;
4310
const signed char InpD = 1; // 'D'
4311
const signed char InpS = 2; // 'S' or 'P'
4312
const signed char InpOB = 3; // [
4313
const signed char InpCB = 4; // ]
4314
const signed char InpPer = 5; // %
4315
const signed char InpGt = 6; // >
4316
const signed char InpUnknown = 7;
4318
static const signed char table[13][8] = {
4319
/* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
4320
{ -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
4321
{ Ws1, -1, -1, -1, -1, -1, -1, -1 }, // Doctype
4322
{ -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
4323
{ Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
4324
{ -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
4325
{ Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
4326
{ -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
4327
{ -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
4328
{ -1, -1, -1, -1, MPE, PER, -1, Mup }, // MPR
4329
{ Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
4330
{ Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
4331
{ -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
4332
{ -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
4337
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
4338
d->startDTDwasReported = FALSE;
4339
d->systemId = QString::null;
4340
d->publicId = QString::null;
4343
state = d->parseStack->top()->state;
4344
d->parseStack->remove();
4345
#if defined(QT_QXML_DEBUG)
4346
qDebug( "QXmlSimpleReader: parseDoctype (cont) in state %d", state );
4348
if ( !d->parseStack->isEmpty() ) {
4349
ParseFunction function = d->parseStack->top()->function;
4350
if ( function == &QXmlSimpleReader::eat_ws ) {
4351
d->parseStack->remove();
4352
#if defined(QT_QXML_DEBUG)
4353
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
4356
if ( !(this->*function)() ) {
4357
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4366
d->doctype = name();
4369
if ( !d->startDTDwasReported && lexicalHnd ) {
4370
d->startDTDwasReported = TRUE;
4371
if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
4372
reportParseError( lexicalHnd->errorString() );
4382
reportParseError( XMLERR_ERRORPARSINGDOCTYPE );
4387
unexpectedEof( &QXmlSimpleReader::parseDoctype, state );
4392
} else if ( c == 'D' ) {
4394
} else if ( c == 'S' ) {
4396
} else if ( c == 'P' ) {
4398
} else if ( c == '[' ) {
4400
} else if ( c == ']' ) {
4402
} else if ( c == '%' ) {
4404
} else if ( c == '>' ) {
4409
state = table[state][input];
4413
d->parseString_s = "DOCTYPE";
4414
if ( !parseString() ) {
4415
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4424
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4429
d->parseName_useRef = FALSE;
4430
if ( !parseName() ) {
4431
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4436
d->parseExternalID_allowPublicID = FALSE;
4437
if ( !parseExternalID() ) {
4438
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4444
if ( !next_eat_ws() ) {
4445
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4450
d->parsePEReference_context = InDTD;
4451
if ( !parsePEReference() ) {
4452
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4457
if ( !parseMarkupdecl() ) {
4458
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4463
if ( !next_eat_ws() ) {
4464
parseFailed( &QXmlSimpleReader::parseDoctype, state );
4470
if ( !d->startDTDwasReported ) {
4471
d->startDTDwasReported = TRUE;
4472
if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
4473
reportParseError( lexicalHnd->errorString() );
4477
if ( !lexicalHnd->endDTD() ) {
4478
reportParseError( lexicalHnd->errorString() );
4489
Parse a ExternalID [75].
4491
If allowPublicID is TRUE parse ExternalID [75] or PublicID [83].
4493
bool QXmlSimpleReader::parseExternalID()
4495
const signed char Init = 0;
4496
const signed char Sys = 1; // parse 'SYSTEM'
4497
const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
4498
const signed char SysSQ = 3; // parse SystemLiteral with '
4499
const signed char SysSQ2 = 4; // parse SystemLiteral with '
4500
const signed char SysDQ = 5; // parse SystemLiteral with "
4501
const signed char SysDQ2 = 6; // parse SystemLiteral with "
4502
const signed char Pub = 7; // parse 'PUBLIC'
4503
const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
4504
const signed char PubSQ = 9; // parse PubidLiteral with '
4505
const signed char PubSQ2 = 10; // parse PubidLiteral with '
4506
const signed char PubDQ = 11; // parse PubidLiteral with "
4507
const signed char PubDQ2 = 12; // parse PubidLiteral with "
4508
const signed char PubE = 13; // finished parsing the PubidLiteral
4509
const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
4510
const signed char PDone = 15; // done if allowPublicID is TRUE
4511
const signed char Done = 16;
4513
const signed char InpSQ = 0; // '
4514
const signed char InpDQ = 1; // "
4515
const signed char InpS = 2; // S
4516
const signed char InpP = 3; // P
4517
const signed char InpWs = 4; // white space
4518
const signed char InpUnknown = 5;
4520
static const signed char table[15][6] = {
4521
/* InpSQ InpDQ InpS InpP InpWs InpUnknown */
4522
{ -1, -1, Sys, Pub, -1, -1 }, // Init
4523
{ -1, -1, -1, -1, SysWS, -1 }, // Sys
4524
{ SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
4525
{ Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
4526
{ Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
4527
{ SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
4528
{ SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
4529
{ -1, -1, -1, -1, PubWS, -1 }, // Pub
4530
{ PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
4531
{ PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
4532
{ PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
4533
{ -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
4534
{ -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
4535
{ PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
4536
{ SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
4541
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
4542
d->systemId = QString::null;
4543
d->publicId = QString::null;
4546
state = d->parseStack->top()->state;
4547
d->parseStack->remove();
4548
#if defined(QT_QXML_DEBUG)
4549
qDebug( "QXmlSimpleReader: parseExternalID (cont) in state %d", state );
4551
if ( !d->parseStack->isEmpty() ) {
4552
ParseFunction function = d->parseStack->top()->function;
4553
if ( function == &QXmlSimpleReader::eat_ws ) {
4554
d->parseStack->remove();
4555
#if defined(QT_QXML_DEBUG)
4556
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
4559
if ( !(this->*function)() ) {
4560
parseFailed( &QXmlSimpleReader::parseExternalID, state );
4569
if ( d->parseExternalID_allowPublicID ) {
4570
d->publicId = string();
4573
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
4580
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
4585
unexpectedEof( &QXmlSimpleReader::parseExternalID, state );
4590
} else if ( c == '\'' ) {
4592
} else if ( c == '"' ) {
4594
} else if ( c == 'S' ) {
4596
} else if ( c == 'P' ) {
4601
state = table[state][input];
4605
d->parseString_s = "SYSTEM";
4606
if ( !parseString() ) {
4607
parseFailed( &QXmlSimpleReader::parseExternalID, state );
4613
parseFailed( &QXmlSimpleReader::parseExternalID, state );
4628
d->parseString_s = "PUBLIC";
4629
if ( !parseString() ) {
4630
parseFailed( &QXmlSimpleReader::parseExternalID, state );
4636
parseFailed( &QXmlSimpleReader::parseExternalID, state );
4654
d->publicId = string();
4656
parseFailed( &QXmlSimpleReader::parseExternalID, state );
4661
d->systemId = string();
4669
Parse a markupdecl [29].
4671
bool QXmlSimpleReader::parseMarkupdecl()
4673
const signed char Init = 0;
4674
const signed char Lt = 1; // < was read
4675
const signed char Em = 2; // ! was read
4676
const signed char CE = 3; // E was read
4677
const signed char Qm = 4; // ? was read
4678
const signed char Dash = 5; // - was read
4679
const signed char CA = 6; // A was read
4680
const signed char CEL = 7; // EL was read
4681
const signed char CEN = 8; // EN was read
4682
const signed char CN = 9; // N was read
4683
const signed char Done = 10;
4685
const signed char InpLt = 0; // <
4686
const signed char InpQm = 1; // ?
4687
const signed char InpEm = 2; // !
4688
const signed char InpDash = 3; // -
4689
const signed char InpA = 4; // A
4690
const signed char InpE = 5; // E
4691
const signed char InpL = 6; // L
4692
const signed char InpN = 7; // N
4693
const signed char InpUnknown = 8;
4695
static const signed char table[4][9] = {
4696
/* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
4697
{ Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
4698
{ -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
4699
{ -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
4700
{ -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
4705
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
4708
state = d->parseStack->top()->state;
4709
d->parseStack->remove();
4710
#if defined(QT_QXML_DEBUG)
4711
qDebug( "QXmlSimpleReader: parseMarkupdecl (cont) in state %d", state );
4713
if ( !d->parseStack->isEmpty() ) {
4714
ParseFunction function = d->parseStack->top()->function;
4715
if ( function == &QXmlSimpleReader::eat_ws ) {
4716
d->parseStack->remove();
4717
#if defined(QT_QXML_DEBUG)
4718
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
4721
if ( !(this->*function)() ) {
4722
parseFailed( &QXmlSimpleReader::parseMarkupdecl, state );
4732
if ( !contentHnd->processingInstruction(name(),string()) ) {
4733
reportParseError( contentHnd->errorString() );
4740
if ( !lexicalHnd->comment( string() ) ) {
4741
reportParseError( lexicalHnd->errorString() );
4758
reportParseError( XMLERR_LETTEREXPECTED );
4763
unexpectedEof( &QXmlSimpleReader::parseMarkupdecl, state );
4768
} else if ( c == '?' ) {
4770
} else if ( c == '!' ) {
4772
} else if ( c == '-' ) {
4774
} else if ( c == 'A' ) {
4776
} else if ( c == 'E' ) {
4778
} else if ( c == 'L' ) {
4780
} else if ( c == 'N' ) {
4785
state = table[state][input];
4798
d->parsePI_xmldecl = FALSE;
4800
parseFailed( &QXmlSimpleReader::parseMarkupdecl, state );
4805
if ( !parseComment() ) {
4806
parseFailed( &QXmlSimpleReader::parseMarkupdecl, state );
4811
if ( !parseAttlistDecl() ) {
4812
parseFailed( &QXmlSimpleReader::parseMarkupdecl, state );
4817
if ( !parseElementDecl() ) {
4818
parseFailed( &QXmlSimpleReader::parseMarkupdecl, state );
4823
if ( !parseEntityDecl() ) {
4824
parseFailed( &QXmlSimpleReader::parseMarkupdecl, state );
4829
if ( !parseNotationDecl() ) {
4830
parseFailed( &QXmlSimpleReader::parseMarkupdecl, state );
4839
Parse a PEReference [69]
4841
bool QXmlSimpleReader::parsePEReference()
4843
const signed char Init = 0;
4844
const signed char Next = 1;
4845
const signed char Name = 2;
4846
const signed char NameR = 3; // same as Name, but already reported
4847
const signed char Done = 4;
4849
const signed char InpSemi = 0; // ;
4850
const signed char InpPer = 1; // %
4851
const signed char InpUnknown = 2;
4853
static const signed char table[4][3] = {
4854
/* InpSemi InpPer InpUnknown */
4855
{ -1, Next, -1 }, // Init
4856
{ -1, -1, Name }, // Next
4857
{ Done, -1, -1 }, // Name
4858
{ Done, -1, -1 } // NameR
4863
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
4866
state = d->parseStack->top()->state;
4867
d->parseStack->remove();
4868
#if defined(QT_QXML_DEBUG)
4869
qDebug( "QXmlSimpleReader: parsePEReference (cont) in state %d", state );
4871
if ( !d->parseStack->isEmpty() ) {
4872
ParseFunction function = d->parseStack->top()->function;
4873
if ( function == &QXmlSimpleReader::eat_ws ) {
4874
d->parseStack->remove();
4875
#if defined(QT_QXML_DEBUG)
4876
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
4879
if ( !(this->*function)() ) {
4880
parseFailed( &QXmlSimpleReader::parsePEReference, state );
4891
QString xmlRefString;
4893
QMap<QString,QString>::Iterator it;
4894
it = d->parameterEntities.find( ref() );
4895
if ( it != d->parameterEntities.end() ) {
4897
xmlRefString = it.data();
4898
} else if ( entityRes ) {
4899
QMap<QString,QXmlSimpleReaderPrivate::ExternParameterEntity>::Iterator it2;
4900
it2 = d->externParameterEntities.find( ref() );
4901
QXmlInputSource *ret = 0;
4902
if ( it2 != d->externParameterEntities.end() ) {
4903
if ( !entityRes->resolveEntity( it2.data().publicId, it2.data().systemId, ret ) ) {
4905
reportParseError( entityRes->errorString() );
4909
xmlRefString = ret->data();
4911
if ( !stripTextDecl( xmlRefString ) ) {
4912
reportParseError( XMLERR_ERRORINTEXTDECL );
4922
if ( !contentHnd->skippedEntity( QString("%") + ref() ) ) {
4923
reportParseError( contentHnd->errorString() );
4928
if ( d->parsePEReference_context == InEntityValue ) {
4929
// Included in literal
4930
if ( !insertXmlRef( xmlRefString, ref(), TRUE ) )
4932
} else if ( d->parsePEReference_context == InDTD ) {
4934
if ( !insertXmlRef( QString(" ")+xmlRefString+QString(" "), ref(), FALSE ) )
4945
reportParseError( XMLERR_LETTEREXPECTED );
4950
unexpectedEof( &QXmlSimpleReader::parsePEReference, state );
4955
} else if ( c == '%' ) {
4960
state = table[state][input];
4968
d->parseName_useRef = TRUE;
4969
if ( !parseName() ) {
4970
parseFailed( &QXmlSimpleReader::parsePEReference, state );
4982
Parse a AttlistDecl [52].
4984
Precondition: the beginning '<!' is already read and the head
4985
stands on the 'A' of '<!ATTLIST'
4987
bool QXmlSimpleReader::parseAttlistDecl()
4989
const signed char Init = 0;
4990
const signed char Attlist = 1; // parse the string "ATTLIST"
4991
const signed char Ws = 2; // whitespace read
4992
const signed char Name = 3; // parse name
4993
const signed char Ws1 = 4; // whitespace read
4994
const signed char Attdef = 5; // parse the AttDef
4995
const signed char Ws2 = 6; // whitespace read
4996
const signed char Atttype = 7; // parse the AttType
4997
const signed char Ws3 = 8; // whitespace read
4998
const signed char DDecH = 9; // DefaultDecl with #
4999
const signed char DefReq = 10; // parse the string "REQUIRED"
5000
const signed char DefImp = 11; // parse the string "IMPLIED"
5001
const signed char DefFix = 12; // parse the string "FIXED"
5002
const signed char Attval = 13; // parse the AttValue
5003
const signed char Ws4 = 14; // whitespace read
5004
const signed char Done = 15;
5006
const signed char InpWs = 0; // white space
5007
const signed char InpGt = 1; // >
5008
const signed char InpHash = 2; // #
5009
const signed char InpA = 3; // A
5010
const signed char InpI = 4; // I
5011
const signed char InpF = 5; // F
5012
const signed char InpR = 6; // R
5013
const signed char InpUnknown = 7;
5015
static const signed char table[15][8] = {
5016
/* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
5017
{ -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
5018
{ Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
5019
{ -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
5020
{ Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
5021
{ -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
5022
{ Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
5023
{ -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
5024
{ Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
5025
{ -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
5026
{ -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
5027
{ Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
5028
{ Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
5029
{ Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
5030
{ Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
5031
{ -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
5036
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
5039
state = d->parseStack->top()->state;
5040
d->parseStack->remove();
5041
#if defined(QT_QXML_DEBUG)
5042
qDebug( "QXmlSimpleReader: parseAttlistDecl (cont) in state %d", state );
5044
if ( !d->parseStack->isEmpty() ) {
5045
ParseFunction function = d->parseStack->top()->function;
5046
if ( function == &QXmlSimpleReader::eat_ws ) {
5047
d->parseStack->remove();
5048
#if defined(QT_QXML_DEBUG)
5049
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
5052
if ( !(this->*function)() ) {
5053
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5062
d->attDeclEName = name();
5065
d->attDeclAName = name();
5071
reportParseError( XMLERR_LETTEREXPECTED );
5076
unexpectedEof( &QXmlSimpleReader::parseAttlistDecl, state );
5081
} else if ( c == '>' ) {
5083
} else if ( c == '#' ) {
5085
} else if ( c == 'A' ) {
5087
} else if ( c == 'I' ) {
5089
} else if ( c == 'F' ) {
5091
} else if ( c == 'R' ) {
5096
state = table[state][input];
5100
d->parseString_s = "ATTLIST";
5101
if ( !parseString() ) {
5102
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5111
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5116
d->parseName_useRef = FALSE;
5117
if ( !parseName() ) {
5118
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5123
d->parseName_useRef = FALSE;
5124
if ( !parseName() ) {
5125
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5130
if ( !parseAttType() ) {
5131
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5139
d->parseString_s = "REQUIRED";
5140
if ( !parseString() ) {
5141
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5146
d->parseString_s = "IMPLIED";
5147
if ( !parseString() ) {
5148
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5153
d->parseString_s = "FIXED";
5154
if ( !parseString() ) {
5155
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5160
if ( !parseAttValue() ) {
5161
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5167
// ### not all values are computed yet...
5168
if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) {
5169
reportParseError( declHnd->errorString() );
5174
parseFailed( &QXmlSimpleReader::parseAttlistDecl, state );
5186
Parse a AttType [54]
5188
bool QXmlSimpleReader::parseAttType()
5190
const signed char Init = 0;
5191
const signed char ST = 1; // StringType
5192
const signed char TTI = 2; // TokenizedType starting with 'I'
5193
const signed char TTI2 = 3; // TokenizedType helpstate
5194
const signed char TTI3 = 4; // TokenizedType helpstate
5195
const signed char TTE = 5; // TokenizedType starting with 'E'
5196
const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
5197
const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
5198
const signed char N = 8; // N read (TokenizedType or Notation)
5199
const signed char TTNM = 9; // TokenizedType starting with 'NM'
5200
const signed char TTNM2 = 10; // TokenizedType helpstate
5201
const signed char NO = 11; // Notation
5202
const signed char NO2 = 12; // Notation helpstate
5203
const signed char NO3 = 13; // Notation helpstate
5204
const signed char NOName = 14; // Notation, read name
5205
const signed char NO4 = 15; // Notation helpstate
5206
const signed char EN = 16; // Enumeration
5207
const signed char ENNmt = 17; // Enumeration, read Nmtoken
5208
const signed char EN2 = 18; // Enumeration helpstate
5209
const signed char ADone = 19; // almost done (make next and accept)
5210
const signed char Done = 20;
5212
const signed char InpWs = 0; // whitespace
5213
const signed char InpOp = 1; // (
5214
const signed char InpCp = 2; // )
5215
const signed char InpPipe = 3; // |
5216
const signed char InpC = 4; // C
5217
const signed char InpE = 5; // E
5218
const signed char InpI = 6; // I
5219
const signed char InpM = 7; // M
5220
const signed char InpN = 8; // N
5221
const signed char InpO = 9; // O
5222
const signed char InpR = 10; // R
5223
const signed char InpS = 11; // S
5224
const signed char InpY = 12; // Y
5225
const signed char InpUnknown = 13;
5227
static const signed char table[19][14] = {
5228
/* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
5229
{ -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
5230
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
5231
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
5232
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
5233
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
5234
{ -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
5235
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
5236
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
5237
{ -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
5238
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
5239
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
5240
{ NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
5241
{ -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
5242
{ NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
5243
{ NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
5244
{ -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
5245
{ -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
5246
{ EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
5247
{ -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
5252
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
5255
state = d->parseStack->top()->state;
5256
d->parseStack->remove();
5257
#if defined(QT_QXML_DEBUG)
5258
qDebug( "QXmlSimpleReader: parseAttType (cont) in state %d", state );
5260
if ( !d->parseStack->isEmpty() ) {
5261
ParseFunction function = d->parseStack->top()->function;
5262
if ( function == &QXmlSimpleReader::eat_ws ) {
5263
d->parseStack->remove();
5264
#if defined(QT_QXML_DEBUG)
5265
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
5268
if ( !(this->*function)() ) {
5269
parseFailed( &QXmlSimpleReader::parseAttType, state );
5283
reportParseError( XMLERR_LETTEREXPECTED );
5288
unexpectedEof( &QXmlSimpleReader::parseAttType, state );
5293
} else if ( c == '(' ) {
5295
} else if ( c == ')' ) {
5297
} else if ( c == '|' ) {
5299
} else if ( c == 'C' ) {
5301
} else if ( c == 'E' ) {
5303
} else if ( c == 'I' ) {
5305
} else if ( c == 'M' ) {
5307
} else if ( c == 'N' ) {
5309
} else if ( c == 'O' ) {
5311
} else if ( c == 'R' ) {
5313
} else if ( c == 'S' ) {
5315
} else if ( c == 'Y' ) {
5320
state = table[state][input];
5324
d->parseString_s = "CDATA";
5325
if ( !parseString() ) {
5326
parseFailed( &QXmlSimpleReader::parseAttType, state );
5331
d->parseString_s = "ID";
5332
if ( !parseString() ) {
5333
parseFailed( &QXmlSimpleReader::parseAttType, state );
5338
d->parseString_s = "REF";
5339
if ( !parseString() ) {
5340
parseFailed( &QXmlSimpleReader::parseAttType, state );
5348
d->parseString_s = "ENTIT";
5349
if ( !parseString() ) {
5350
parseFailed( &QXmlSimpleReader::parseAttType, state );
5358
d->parseString_s = "IES";
5359
if ( !parseString() ) {
5360
parseFailed( &QXmlSimpleReader::parseAttType, state );
5368
d->parseString_s = "MTOKEN";
5369
if ( !parseString() ) {
5370
parseFailed( &QXmlSimpleReader::parseAttType, state );
5378
d->parseString_s = "OTATION";
5379
if ( !parseString() ) {
5380
parseFailed( &QXmlSimpleReader::parseAttType, state );
5386
parseFailed( &QXmlSimpleReader::parseAttType, state );
5391
if ( !next_eat_ws() ) {
5392
parseFailed( &QXmlSimpleReader::parseAttType, state );
5397
d->parseName_useRef = FALSE;
5398
if ( !parseName() ) {
5399
parseFailed( &QXmlSimpleReader::parseAttType, state );
5405
parseFailed( &QXmlSimpleReader::parseAttType, state );
5410
if ( !next_eat_ws() ) {
5411
parseFailed( &QXmlSimpleReader::parseAttType, state );
5416
if ( !parseNmtoken() ) {
5417
parseFailed( &QXmlSimpleReader::parseAttType, state );
5423
parseFailed( &QXmlSimpleReader::parseAttType, state );
5435
Parse a AttValue [10]
5437
Precondition: the head stands on the beginning " or '
5439
If this function was successful, the head stands on the first
5440
character after the closing " or ' and the value of the attribute
5443
bool QXmlSimpleReader::parseAttValue()
5445
const signed char Init = 0;
5446
const signed char Dq = 1; // double quotes were read
5447
const signed char DqRef = 2; // read references in double quotes
5448
const signed char DqC = 3; // signed character read in double quotes
5449
const signed char Sq = 4; // single quotes were read
5450
const signed char SqRef = 5; // read references in single quotes
5451
const signed char SqC = 6; // signed character read in single quotes
5452
const signed char Done = 7;
5454
const signed char InpDq = 0; // "
5455
const signed char InpSq = 1; // '
5456
const signed char InpAmp = 2; // &
5457
const signed char InpLt = 3; // <
5458
const signed char InpUnknown = 4;
5460
static const signed char table[7][5] = {
5461
/* InpDq InpSq InpAmp InpLt InpUnknown */
5462
{ Dq, Sq, -1, -1, -1 }, // Init
5463
{ Done, DqC, DqRef, -1, DqC }, // Dq
5464
{ Done, DqC, DqRef, -1, DqC }, // DqRef
5465
{ Done, DqC, DqRef, -1, DqC }, // DqC
5466
{ SqC, Done, SqRef, -1, SqC }, // Sq
5467
{ SqC, Done, SqRef, -1, SqC }, // SqRef
5468
{ SqC, Done, SqRef, -1, SqC } // SqRef
5473
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
5476
state = d->parseStack->top()->state;
5477
d->parseStack->remove();
5478
#if defined(QT_QXML_DEBUG)
5479
qDebug( "QXmlSimpleReader: parseAttValue (cont) in state %d", state );
5481
if ( !d->parseStack->isEmpty() ) {
5482
ParseFunction function = d->parseStack->top()->function;
5483
if ( function == &QXmlSimpleReader::eat_ws ) {
5484
d->parseStack->remove();
5485
#if defined(QT_QXML_DEBUG)
5486
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
5489
if ( !(this->*function)() ) {
5490
parseFailed( &QXmlSimpleReader::parseAttValue, state );
5502
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
5507
unexpectedEof( &QXmlSimpleReader::parseAttValue, state );
5512
} else if ( c == '\'' ) {
5514
} else if ( c == '&' ) {
5516
} else if ( c == '<' ) {
5521
state = table[state][input];
5531
d->parseReference_context = InAttributeValue;
5532
if ( !parseReference() ) {
5533
parseFailed( &QXmlSimpleReader::parseAttValue, state );
5550
Parse a elementdecl [45].
5552
Precondition: the beginning '<!E' is already read and the head
5553
stands on the 'L' of '<!ELEMENT'
5555
bool QXmlSimpleReader::parseElementDecl()
5557
const signed char Init = 0;
5558
const signed char Elem = 1; // parse the beginning string
5559
const signed char Ws1 = 2; // whitespace required
5560
const signed char Nam = 3; // parse Name
5561
const signed char Ws2 = 4; // whitespace required
5562
const signed char Empty = 5; // read EMPTY
5563
const signed char Any = 6; // read ANY
5564
const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
5565
const signed char Mix = 8; // read Mixed
5566
const signed char Mix2 = 9; //
5567
const signed char Mix3 = 10; //
5568
const signed char MixN1 = 11; //
5569
const signed char MixN2 = 12; //
5570
const signed char MixN3 = 13; //
5571
const signed char MixN4 = 14; //
5572
const signed char Cp = 15; // parse cp
5573
const signed char Cp2 = 16; //
5574
const signed char WsD = 17; // eat whitespace before Done
5575
const signed char Done = 18;
5577
const signed char InpWs = 0;
5578
const signed char InpGt = 1; // >
5579
const signed char InpPipe = 2; // |
5580
const signed char InpOp = 3; // (
5581
const signed char InpCp = 4; // )
5582
const signed char InpHash = 5; // #
5583
const signed char InpQm = 6; // ?
5584
const signed char InpAst = 7; // *
5585
const signed char InpPlus = 8; // +
5586
const signed char InpA = 9; // A
5587
const signed char InpE = 10; // E
5588
const signed char InpL = 11; // L
5589
const signed char InpUnknown = 12;
5591
static const signed char table[18][13] = {
5592
/* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
5593
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
5594
{ Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
5595
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
5596
{ Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
5597
{ -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
5598
{ WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
5599
{ WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
5600
{ -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
5601
{ Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
5602
{ -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
5603
{ WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
5604
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
5605
{ MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
5606
{ -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
5607
{ -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
5608
{ WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
5609
{ WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
5610
{ -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
5615
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
5618
state = d->parseStack->top()->state;
5619
d->parseStack->remove();
5620
#if defined(QT_QXML_DEBUG)
5621
qDebug( "QXmlSimpleReader: parseElementDecl (cont) in state %d", state );
5623
if ( !d->parseStack->isEmpty() ) {
5624
ParseFunction function = d->parseStack->top()->function;
5625
if ( function == &QXmlSimpleReader::eat_ws ) {
5626
d->parseStack->remove();
5627
#if defined(QT_QXML_DEBUG)
5628
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
5631
if ( !(this->*function)() ) {
5632
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5643
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
5648
unexpectedEof( &QXmlSimpleReader::parseElementDecl, state );
5653
} else if ( c == '>' ) {
5655
} else if ( c == '|' ) {
5657
} else if ( c == '(' ) {
5659
} else if ( c == ')' ) {
5661
} else if ( c == '#' ) {
5663
} else if ( c == '?' ) {
5665
} else if ( c == '*' ) {
5667
} else if ( c == '+' ) {
5669
} else if ( c == 'A' ) {
5671
} else if ( c == 'E' ) {
5673
} else if ( c == 'L' ) {
5678
state = table[state][input];
5682
d->parseString_s = "LEMENT";
5683
if ( !parseString() ) {
5684
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5690
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5695
d->parseName_useRef = FALSE;
5696
if ( !parseName() ) {
5697
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5703
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5708
d->parseString_s = "EMPTY";
5709
if ( !parseString() ) {
5710
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5715
d->parseString_s = "ANY";
5716
if ( !parseString() ) {
5717
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5722
if ( !next_eat_ws() ) {
5723
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5728
d->parseString_s = "#PCDATA";
5729
if ( !parseString() ) {
5730
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5736
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5744
if ( !next_eat_ws() ) {
5745
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5750
d->parseName_useRef = FALSE;
5751
if ( !parseName() ) {
5752
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5758
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5766
if ( !parseChoiceSeq() ) {
5767
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5775
if ( !next_eat_ws() ) {
5776
parseFailed( &QXmlSimpleReader::parseElementDecl, state );
5788
Parse a NotationDecl [82].
5790
Precondition: the beginning '<!' is already read and the head
5791
stands on the 'N' of '<!NOTATION'
5793
bool QXmlSimpleReader::parseNotationDecl()
5795
const signed char Init = 0;
5796
const signed char Not = 1; // read NOTATION
5797
const signed char Ws1 = 2; // eat whitespaces
5798
const signed char Nam = 3; // read Name
5799
const signed char Ws2 = 4; // eat whitespaces
5800
const signed char ExtID = 5; // parse ExternalID
5801
const signed char ExtIDR = 6; // same as ExtID, but already reported
5802
const signed char Ws3 = 7; // eat whitespaces
5803
const signed char Done = 8;
5805
const signed char InpWs = 0;
5806
const signed char InpGt = 1; // >
5807
const signed char InpN = 2; // N
5808
const signed char InpUnknown = 3;
5810
static const signed char table[8][4] = {
5811
/* InpWs InpGt InpN InpUnknown */
5812
{ -1, -1, Not, -1 }, // Init
5813
{ Ws1, -1, -1, -1 }, // Not
5814
{ -1, -1, Nam, Nam }, // Ws1
5815
{ Ws2, Done, -1, -1 }, // Nam
5816
{ -1, Done, ExtID, ExtID }, // Ws2
5817
{ Ws3, Done, -1, -1 }, // ExtID
5818
{ Ws3, Done, -1, -1 }, // ExtIDR
5819
{ -1, Done, -1, -1 } // Ws3
5824
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
5827
state = d->parseStack->top()->state;
5828
d->parseStack->remove();
5829
#if defined(QT_QXML_DEBUG)
5830
qDebug( "QXmlSimpleReader: parseNotationDecl (cont) in state %d", state );
5832
if ( !d->parseStack->isEmpty() ) {
5833
ParseFunction function = d->parseStack->top()->function;
5834
if ( function == &QXmlSimpleReader::eat_ws ) {
5835
d->parseStack->remove();
5836
#if defined(QT_QXML_DEBUG)
5837
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
5840
if ( !(this->*function)() ) {
5841
parseFailed( &QXmlSimpleReader::parseNotationDecl, state );
5852
if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) {
5853
reportParseError( dtdHnd->errorString() );
5863
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
5868
unexpectedEof( &QXmlSimpleReader::parseNotationDecl, state );
5873
} else if ( c == '>' ) {
5875
} else if ( c == 'N' ) {
5880
state = table[state][input];
5884
d->parseString_s = "NOTATION";
5885
if ( !parseString() ) {
5886
parseFailed( &QXmlSimpleReader::parseNotationDecl, state );
5892
parseFailed( &QXmlSimpleReader::parseNotationDecl, state );
5897
d->parseName_useRef = FALSE;
5898
if ( !parseName() ) {
5899
parseFailed( &QXmlSimpleReader::parseNotationDecl, state );
5905
parseFailed( &QXmlSimpleReader::parseNotationDecl, state );
5911
d->parseExternalID_allowPublicID = TRUE;
5912
if ( !parseExternalID() ) {
5913
parseFailed( &QXmlSimpleReader::parseNotationDecl, state );
5919
parseFailed( &QXmlSimpleReader::parseNotationDecl, state );
5931
Parse choice [49] or seq [50].
5933
Precondition: the beginning '('S? is already read and the head
5934
stands on the first non-whitespace character after it.
5936
bool QXmlSimpleReader::parseChoiceSeq()
5938
const signed char Init = 0;
5939
const signed char Ws1 = 1; // eat whitespace
5940
const signed char CS = 2; // choice or set
5941
const signed char Ws2 = 3; // eat whitespace
5942
const signed char More = 4; // more cp to read
5943
const signed char Name = 5; // read name
5944
const signed char Done = 6; //
5946
const signed char InpWs = 0; // S
5947
const signed char InpOp = 1; // (
5948
const signed char InpCp = 2; // )
5949
const signed char InpQm = 3; // ?
5950
const signed char InpAst = 4; // *
5951
const signed char InpPlus = 5; // +
5952
const signed char InpPipe = 6; // |
5953
const signed char InpComm = 7; // ,
5954
const signed char InpUnknown = 8;
5956
static const signed char table[6][9] = {
5957
/* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
5958
{ -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
5959
{ -1, CS, -1, -1, -1, -1, -1, -1, CS }, // Ws1
5960
{ Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS
5961
{ -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
5962
{ -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
5963
{ Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS)
5968
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
5971
state = d->parseStack->top()->state;
5972
d->parseStack->remove();
5973
#if defined(QT_QXML_DEBUG)
5974
qDebug( "QXmlSimpleReader: parseChoiceSeq (cont) in state %d", state );
5976
if ( !d->parseStack->isEmpty() ) {
5977
ParseFunction function = d->parseStack->top()->function;
5978
if ( function == &QXmlSimpleReader::eat_ws ) {
5979
d->parseStack->remove();
5980
#if defined(QT_QXML_DEBUG)
5981
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
5984
if ( !(this->*function)() ) {
5985
parseFailed( &QXmlSimpleReader::parseChoiceSeq, state );
5997
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
6002
unexpectedEof( &QXmlSimpleReader::parseChoiceSeq, state );
6007
} else if ( c == '(' ) {
6009
} else if ( c == ')' ) {
6011
} else if ( c == '?' ) {
6013
} else if ( c == '*' ) {
6015
} else if ( c == '+' ) {
6017
} else if ( c == '|' ) {
6019
} else if ( c == ',' ) {
6024
state = table[state][input];
6028
if ( !next_eat_ws() ) {
6029
parseFailed( &QXmlSimpleReader::parseChoiceSeq, state );
6034
if ( !parseChoiceSeq() ) {
6035
parseFailed( &QXmlSimpleReader::parseChoiceSeq, state );
6040
if ( !next_eat_ws() ) {
6041
parseFailed( &QXmlSimpleReader::parseChoiceSeq, state );
6046
if ( !next_eat_ws() ) {
6047
parseFailed( &QXmlSimpleReader::parseChoiceSeq, state );
6052
d->parseName_useRef = FALSE;
6053
if ( !parseName() ) {
6054
parseFailed( &QXmlSimpleReader::parseChoiceSeq, state );
6066
Parse a EntityDecl [70].
6068
Precondition: the beginning '<!E' is already read and the head
6069
stand on the 'N' of '<!ENTITY'
6071
bool QXmlSimpleReader::parseEntityDecl()
6073
const signed char Init = 0;
6074
const signed char Ent = 1; // parse "ENTITY"
6075
const signed char Ws1 = 2; // white space read
6076
const signed char Name = 3; // parse name
6077
const signed char Ws2 = 4; // white space read
6078
const signed char EValue = 5; // parse entity value
6079
const signed char EValueR = 6; // same as EValue, but already reported
6080
const signed char ExtID = 7; // parse ExternalID
6081
const signed char Ws3 = 8; // white space read
6082
const signed char Ndata = 9; // parse "NDATA"
6083
const signed char Ws4 = 10; // white space read
6084
const signed char NNam = 11; // parse name
6085
const signed char NNamR = 12; // same as NNam, but already reported
6086
const signed char PEDec = 13; // parse PEDecl
6087
const signed char Ws6 = 14; // white space read
6088
const signed char PENam = 15; // parse name
6089
const signed char Ws7 = 16; // white space read
6090
const signed char PEVal = 17; // parse entity value
6091
const signed char PEValR = 18; // same as PEVal, but already reported
6092
const signed char PEEID = 19; // parse ExternalID
6093
const signed char PEEIDR = 20; // same as PEEID, but already reported
6094
const signed char WsE = 21; // white space read
6095
const signed char Done = 22;
6096
const signed char EDDone = 23; // done, but also report an external, unparsed entity decl
6098
const signed char InpWs = 0; // white space
6099
const signed char InpPer = 1; // %
6100
const signed char InpQuot = 2; // " or '
6101
const signed char InpGt = 3; // >
6102
const signed char InpN = 4; // N
6103
const signed char InpUnknown = 5;
6105
static const signed char table[22][6] = {
6106
/* InpWs InpPer InpQuot InpGt InpN InpUnknown */
6107
{ -1, -1, -1, -1, Ent, -1 }, // Init
6108
{ Ws1, -1, -1, -1, -1, -1 }, // Ent
6109
{ -1, PEDec, -1, -1, Name, Name }, // Ws1
6110
{ Ws2, -1, -1, -1, -1, -1 }, // Name
6111
{ -1, -1, EValue, -1, -1, ExtID }, // Ws2
6112
{ WsE, -1, -1, Done, -1, -1 }, // EValue
6113
{ WsE, -1, -1, Done, -1, -1 }, // EValueR
6114
{ Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
6115
{ -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
6116
{ Ws4, -1, -1, -1, -1, -1 }, // Ndata
6117
{ -1, -1, -1, -1, NNam, NNam }, // Ws4
6118
{ WsE, -1, -1, Done, -1, -1 }, // NNam
6119
{ WsE, -1, -1, Done, -1, -1 }, // NNamR
6120
{ Ws6, -1, -1, -1, -1, -1 }, // PEDec
6121
{ -1, -1, -1, -1, PENam, PENam }, // Ws6
6122
{ Ws7, -1, -1, -1, -1, -1 }, // PENam
6123
{ -1, -1, PEVal, -1, -1, PEEID }, // Ws7
6124
{ WsE, -1, -1, Done, -1, -1 }, // PEVal
6125
{ WsE, -1, -1, Done, -1, -1 }, // PEValR
6126
{ WsE, -1, -1, Done, -1, -1 }, // PEEID
6127
{ WsE, -1, -1, Done, -1, -1 }, // PEEIDR
6128
{ -1, -1, -1, Done, -1, -1 } // WsE
6133
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
6136
state = d->parseStack->top()->state;
6137
d->parseStack->remove();
6138
#if defined(QT_QXML_DEBUG)
6139
qDebug( "QXmlSimpleReader: parseEntityDecl (cont) in state %d", state );
6141
if ( !d->parseStack->isEmpty() ) {
6142
ParseFunction function = d->parseStack->top()->function;
6143
if ( function == &QXmlSimpleReader::eat_ws ) {
6144
d->parseStack->remove();
6145
#if defined(QT_QXML_DEBUG)
6146
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
6149
if ( !(this->*function)() ) {
6150
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6159
if ( !entityExist( name() ) ) {
6160
d->entities.insert( name(), string() );
6162
if ( !declHnd->internalEntityDecl( name(), string() ) ) {
6163
reportParseError( declHnd->errorString() );
6171
if ( !entityExist( name() ) ) {
6172
d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
6174
if ( !dtdHnd->unparsedEntityDecl( name(), d->publicId, d->systemId, ref() ) ) {
6175
reportParseError( declHnd->errorString() );
6183
if ( !entityExist( name() ) ) {
6184
d->parameterEntities.insert( name(), string() );
6186
if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) {
6187
reportParseError( declHnd->errorString() );
6195
if ( !entityExist( name() ) ) {
6196
d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
6198
if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) {
6199
reportParseError( declHnd->errorString() );
6207
if ( !entityExist( name() ) ) {
6208
d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, QString::null ) );
6210
if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
6211
reportParseError( declHnd->errorString() );
6221
reportParseError( XMLERR_LETTEREXPECTED );
6226
unexpectedEof( &QXmlSimpleReader::parseEntityDecl, state );
6231
} else if ( c == '%' ) {
6233
} else if ( c == '"' || c == '\'' ) {
6235
} else if ( c == '>' ) {
6237
} else if ( c == 'N' ) {
6242
state = table[state][input];
6246
d->parseString_s = "NTITY";
6247
if ( !parseString() ) {
6248
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6254
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6259
d->parseName_useRef = FALSE;
6260
if ( !parseName() ) {
6261
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6267
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6273
if ( !parseEntityValue() ) {
6274
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6279
d->parseExternalID_allowPublicID = FALSE;
6280
if ( !parseExternalID() ) {
6281
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6287
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6292
d->parseString_s = "NDATA";
6293
if ( !parseString() ) {
6294
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6300
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6306
d->parseName_useRef = TRUE;
6307
if ( !parseName() ) {
6308
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6317
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6322
d->parseName_useRef = FALSE;
6323
if ( !parseName() ) {
6324
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6330
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6336
if ( !parseEntityValue() ) {
6337
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6343
d->parseExternalID_allowPublicID = FALSE;
6344
if ( !parseExternalID() ) {
6345
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6351
parseFailed( &QXmlSimpleReader::parseEntityDecl, state );
6366
Parse a EntityValue [9]
6368
bool QXmlSimpleReader::parseEntityValue()
6370
const signed char Init = 0;
6371
const signed char Dq = 1; // EntityValue is double quoted
6372
const signed char DqC = 2; // signed character
6373
const signed char DqPER = 3; // PERefence
6374
const signed char DqRef = 4; // Reference
6375
const signed char Sq = 5; // EntityValue is double quoted
6376
const signed char SqC = 6; // signed character
6377
const signed char SqPER = 7; // PERefence
6378
const signed char SqRef = 8; // Reference
6379
const signed char Done = 9;
6381
const signed char InpDq = 0; // "
6382
const signed char InpSq = 1; // '
6383
const signed char InpAmp = 2; // &
6384
const signed char InpPer = 3; // %
6385
const signed char InpUnknown = 4;
6387
static const signed char table[9][5] = {
6388
/* InpDq InpSq InpAmp InpPer InpUnknown */
6389
{ Dq, Sq, -1, -1, -1 }, // Init
6390
{ Done, DqC, DqRef, DqPER, DqC }, // Dq
6391
{ Done, DqC, DqRef, DqPER, DqC }, // DqC
6392
{ Done, DqC, DqRef, DqPER, DqC }, // DqPER
6393
{ Done, DqC, DqRef, DqPER, DqC }, // DqRef
6394
{ SqC, Done, SqRef, SqPER, SqC }, // Sq
6395
{ SqC, Done, SqRef, SqPER, SqC }, // SqC
6396
{ SqC, Done, SqRef, SqPER, SqC }, // SqPER
6397
{ SqC, Done, SqRef, SqPER, SqC } // SqRef
6402
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
6405
state = d->parseStack->top()->state;
6406
d->parseStack->remove();
6407
#if defined(QT_QXML_DEBUG)
6408
qDebug( "QXmlSimpleReader: parseEntityValue (cont) in state %d", state );
6410
if ( !d->parseStack->isEmpty() ) {
6411
ParseFunction function = d->parseStack->top()->function;
6412
if ( function == &QXmlSimpleReader::eat_ws ) {
6413
d->parseStack->remove();
6414
#if defined(QT_QXML_DEBUG)
6415
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
6418
if ( !(this->*function)() ) {
6419
parseFailed( &QXmlSimpleReader::parseEntityValue, state );
6431
reportParseError( XMLERR_LETTEREXPECTED );
6436
unexpectedEof( &QXmlSimpleReader::parseEntityValue, state );
6441
} else if ( c == '\'' ) {
6443
} else if ( c == '&' ) {
6445
} else if ( c == '%' ) {
6450
state = table[state][input];
6465
d->parsePEReference_context = InEntityValue;
6466
if ( !parsePEReference() ) {
6467
parseFailed( &QXmlSimpleReader::parseEntityValue, state );
6473
d->parseReference_context = InEntityValue;
6474
if ( !parseReference() ) {
6475
parseFailed( &QXmlSimpleReader::parseEntityValue, state );
6487
Parse a comment [15].
6489
Precondition: the beginning '<!' of the comment is already read and the head
6490
stands on the first '-' of '<!--'.
6492
If this funktion was successful, the head-position is on the first
6493
character after the comment.
6495
bool QXmlSimpleReader::parseComment()
6497
const signed char Init = 0;
6498
const signed char Dash1 = 1; // the first dash was read
6499
const signed char Dash2 = 2; // the second dash was read
6500
const signed char Com = 3; // read comment
6501
const signed char Com2 = 4; // read comment (help state)
6502
const signed char ComE = 5; // finished reading comment
6503
const signed char Done = 6;
6505
const signed char InpDash = 0; // -
6506
const signed char InpGt = 1; // >
6507
const signed char InpUnknown = 2;
6509
static const signed char table[6][3] = {
6510
/* InpDash InpGt InpUnknown */
6511
{ Dash1, -1, -1 }, // Init
6512
{ Dash2, -1, -1 }, // Dash1
6513
{ Com2, Com, Com }, // Dash2
6514
{ Com2, Com, Com }, // Com
6515
{ ComE, Com, Com }, // Com2
6516
{ -1, Done, -1 } // ComE
6521
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
6524
state = d->parseStack->top()->state;
6525
d->parseStack->remove();
6526
#if defined(QT_QXML_DEBUG)
6527
qDebug( "QXmlSimpleReader: parseComment (cont) in state %d", state );
6529
if ( !d->parseStack->isEmpty() ) {
6530
ParseFunction function = d->parseStack->top()->function;
6531
if ( function == &QXmlSimpleReader::eat_ws ) {
6532
d->parseStack->remove();
6533
#if defined(QT_QXML_DEBUG)
6534
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
6537
if ( !(this->*function)() ) {
6538
parseFailed( &QXmlSimpleReader::parseComment, state );
6550
// if next character is not a dash than don't skip it
6551
if ( !atEnd() && c != '-' )
6558
reportParseError( XMLERR_ERRORPARSINGCOMMENT );
6563
unexpectedEof( &QXmlSimpleReader::parseComment, state );
6568
} else if ( c == '>' ) {
6573
state = table[state][input];
6600
Parse an Attribute [41].
6602
Precondition: the head stands on the first character of the name
6603
of the attribute (i.e. all whitespaces are already parsed).
6605
The head stand on the next character after the end quotes. The
6606
variable name contains the name of the attribute and the variable
6607
string contains the value of the attribute.
6609
bool QXmlSimpleReader::parseAttribute()
6611
const signed char Init = 0;
6612
const signed char PName = 1; // parse name
6613
const signed char Ws = 2; // eat ws
6614
const signed char Eq = 3; // the '=' was read
6615
const signed char Quotes = 4; // " or ' were read
6617
const signed char InpNameBe = 0;
6618
const signed char InpEq = 1; // =
6619
const signed char InpDq = 2; // "
6620
const signed char InpSq = 3; // '
6621
const signed char InpUnknown = 4;
6623
static const signed char table[4][5] = {
6624
/* InpNameBe InpEq InpDq InpSq InpUnknown */
6625
{ PName, -1, -1, -1, -1 }, // Init
6626
{ -1, Eq, -1, -1, Ws }, // PName
6627
{ -1, Eq, -1, -1, -1 }, // Ws
6628
{ -1, -1, Quotes, Quotes, -1 } // Eq
6633
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
6636
state = d->parseStack->top()->state;
6637
d->parseStack->remove();
6638
#if defined(QT_QXML_DEBUG)
6639
qDebug( "QXmlSimpleReader: parseAttribute (cont) in state %d", state );
6641
if ( !d->parseStack->isEmpty() ) {
6642
ParseFunction function = d->parseStack->top()->function;
6643
if ( function == &QXmlSimpleReader::eat_ws ) {
6644
d->parseStack->remove();
6645
#if defined(QT_QXML_DEBUG)
6646
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
6649
if ( !(this->*function)() ) {
6650
parseFailed( &QXmlSimpleReader::parseAttribute, state );
6663
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
6668
unexpectedEof( &QXmlSimpleReader::parseAttribute, state );
6671
if ( is_NameBeginning(c) ) {
6673
} else if ( c == '=' ) {
6675
} else if ( c == '"' ) {
6677
} else if ( c == '\'' ) {
6682
state = table[state][input];
6686
d->parseName_useRef = FALSE;
6687
if ( !parseName() ) {
6688
parseFailed( &QXmlSimpleReader::parseAttribute, state );
6694
parseFailed( &QXmlSimpleReader::parseAttribute, state );
6699
if ( !next_eat_ws() ) {
6700
parseFailed( &QXmlSimpleReader::parseAttribute, state );
6705
if ( !parseAttValue() ) {
6706
parseFailed( &QXmlSimpleReader::parseAttribute, state );
6715
Parse a Name [5] and store the name in name or ref (if useRef is TRUE).
6717
bool QXmlSimpleReader::parseName()
6719
const signed char Init = 0;
6720
const signed char Name1 = 1; // parse first signed character of the name
6721
const signed char Name = 2; // parse name
6722
const signed char Done = 3;
6724
const signed char InpNameBe = 0; // name beginning signed characters
6725
const signed char InpNameCh = 1; // NameChar without InpNameBe
6726
const signed char InpUnknown = 2;
6728
static const signed char table[3][3] = {
6729
/* InpNameBe InpNameCh InpUnknown */
6730
{ Name1, -1, -1 }, // Init
6731
{ Name, Name, Done }, // Name1
6732
{ Name, Name, Done } // Name
6737
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
6740
state = d->parseStack->top()->state;
6741
d->parseStack->remove();
6742
#if defined(QT_QXML_DEBUG)
6743
qDebug( "QXmlSimpleReader: parseName (cont) in state %d", state );
6745
if ( !d->parseStack->isEmpty() ) {
6746
ParseFunction function = d->parseStack->top()->function;
6747
if ( function == &QXmlSimpleReader::eat_ws ) {
6748
d->parseStack->remove();
6749
#if defined(QT_QXML_DEBUG)
6750
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
6753
if ( !(this->*function)() ) {
6754
parseFailed( &QXmlSimpleReader::parseName, state );
6766
reportParseError( XMLERR_LETTEREXPECTED );
6771
unexpectedEof( &QXmlSimpleReader::parseName, state );
6774
if ( is_NameBeginning(c) ) {
6776
} else if ( is_NameChar(c) ) {
6781
state = table[state][input];
6785
if ( d->parseName_useRef ) {
6795
if ( d->parseName_useRef ) {
6807
Parse a Nmtoken [7] and store the name in name.
6809
bool QXmlSimpleReader::parseNmtoken()
6811
const signed char Init = 0;
6812
const signed char NameF = 1;
6813
const signed char Name = 2;
6814
const signed char Done = 3;
6816
const signed char InpNameCh = 0; // NameChar without InpNameBe
6817
const signed char InpUnknown = 1;
6819
static const signed char table[3][2] = {
6820
/* InpNameCh InpUnknown */
6821
{ NameF, -1 }, // Init
6822
{ Name, Done }, // NameF
6823
{ Name, Done } // Name
6828
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
6831
state = d->parseStack->top()->state;
6832
d->parseStack->remove();
6833
#if defined(QT_QXML_DEBUG)
6834
qDebug( "QXmlSimpleReader: parseNmtoken (cont) in state %d", state );
6836
if ( !d->parseStack->isEmpty() ) {
6837
ParseFunction function = d->parseStack->top()->function;
6838
if ( function == &QXmlSimpleReader::eat_ws ) {
6839
d->parseStack->remove();
6840
#if defined(QT_QXML_DEBUG)
6841
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
6844
if ( !(this->*function)() ) {
6845
parseFailed( &QXmlSimpleReader::parseNmtoken, state );
6857
reportParseError( XMLERR_LETTEREXPECTED );
6862
unexpectedEof( &QXmlSimpleReader::parseNmtoken, state );
6865
if ( is_NameChar(c) ) {
6870
state = table[state][input];
6887
Parse a Reference [67].
6889
parseReference_charDataRead is set to TRUE if the reference must not be
6890
parsed. The character(s) which the reference mapped to are appended to
6891
string. The head stands on the first character after the reference.
6893
parseReference_charDataRead is set to FALSE if the reference must be parsed.
6894
The charachter(s) which the reference mapped to are inserted at the reference
6895
position. The head stands on the first character of the replacement).
6897
bool QXmlSimpleReader::parseReference()
6899
// temporary variables (only used in very local context, so they don't
6900
// interfere with incremental parsing)
6904
const signed char Init = 0;
6905
const signed char SRef = 1; // start of a reference
6906
const signed char ChRef = 2; // parse CharRef
6907
const signed char ChDec = 3; // parse CharRef decimal
6908
const signed char ChHexS = 4; // start CharRef hexadecimal
6909
const signed char ChHex = 5; // parse CharRef hexadecimal
6910
const signed char Name = 6; // parse name
6911
const signed char DoneD = 7; // done CharRef decimal
6912
const signed char DoneH = 8; // done CharRef hexadecimal
6913
const signed char DoneN = 9; // done EntityRef
6915
const signed char InpAmp = 0; // &
6916
const signed char InpSemi = 1; // ;
6917
const signed char InpHash = 2; // #
6918
const signed char InpX = 3; // x
6919
const signed char InpNum = 4; // 0-9
6920
const signed char InpHex = 5; // a-f A-F
6921
const signed char InpUnknown = 6;
6923
static const signed char table[8][7] = {
6924
/* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
6925
{ SRef, -1, -1, -1, -1, -1, -1 }, // Init
6926
{ -1, -1, ChRef, Name, Name, Name, Name }, // SRef
6927
{ -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
6928
{ -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
6929
{ -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
6930
{ -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
6931
{ -1, DoneN, -1, -1, -1, -1, -1 } // Name
6936
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
6937
d->parseReference_charDataRead = FALSE;
6940
state = d->parseStack->top()->state;
6941
d->parseStack->remove();
6942
#if defined(QT_QXML_DEBUG)
6943
qDebug( "QXmlSimpleReader: parseReference (cont) in state %d", state );
6945
if ( !d->parseStack->isEmpty() ) {
6946
ParseFunction function = d->parseStack->top()->function;
6947
if ( function == &QXmlSimpleReader::eat_ws ) {
6948
d->parseStack->remove();
6949
#if defined(QT_QXML_DEBUG)
6950
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
6953
if ( !(this->*function)() ) {
6954
parseFailed( &QXmlSimpleReader::parseReference, state );
6970
reportParseError( XMLERR_ERRORPARSINGREFERENCE );
6975
unexpectedEof( &QXmlSimpleReader::parseReference, state );
6980
} else if ( c.cell() == '&' ) {
6982
} else if ( c.cell() == ';' ) {
6984
} else if ( c.cell() == '#' ) {
6986
} else if ( c.cell() == 'x' ) {
6988
} else if ( '0' <= c.cell() && c.cell() <= '9' ) {
6990
} else if ( 'a' <= c.cell() && c.cell() <= 'f' ) {
6992
} else if ( 'A' <= c.cell() && c.cell() <= 'F' ) {
6997
state = table[state][input];
7019
// read the name into the ref
7020
d->parseName_useRef = TRUE;
7021
if ( !parseName() ) {
7022
parseFailed( &QXmlSimpleReader::parseReference, state );
7027
tmp = ref().toUInt( &ok, 10 );
7029
stringAddC( QChar(tmp) );
7031
reportParseError( XMLERR_ERRORPARSINGREFERENCE );
7034
d->parseReference_charDataRead = TRUE;
7038
tmp = ref().toUInt( &ok, 16 );
7040
stringAddC( QChar(tmp) );
7042
reportParseError( XMLERR_ERRORPARSINGREFERENCE );
7045
d->parseReference_charDataRead = TRUE;
7049
if ( !processReference() )
7058
Helper function for parseReference()
7060
bool QXmlSimpleReader::processReference()
7062
QString reference = ref();
7063
if ( reference == "amp" ) {
7064
if ( d->parseReference_context == InEntityValue ) {
7066
stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
7068
// Included or Included in literal
7071
d->parseReference_charDataRead = TRUE;
7072
} else if ( reference == "lt" ) {
7073
if ( d->parseReference_context == InEntityValue ) {
7075
stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
7077
// Included or Included in literal
7080
d->parseReference_charDataRead = TRUE;
7081
} else if ( reference == "gt" ) {
7082
if ( d->parseReference_context == InEntityValue ) {
7084
stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
7086
// Included or Included in literal
7089
d->parseReference_charDataRead = TRUE;
7090
} else if ( reference == "apos" ) {
7091
if ( d->parseReference_context == InEntityValue ) {
7093
stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
7095
// Included or Included in literal
7098
d->parseReference_charDataRead = TRUE;
7099
} else if ( reference == "quot" ) {
7100
if ( d->parseReference_context == InEntityValue ) {
7102
stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
7104
// Included or Included in literal
7107
d->parseReference_charDataRead = TRUE;
7109
QMap<QString,QString>::Iterator it;
7110
it = d->entities.find( reference );
7111
if ( it != d->entities.end() ) {
7112
// "Internal General"
7113
switch ( d->parseReference_context ) {
7116
if ( !insertXmlRef( it.data(), reference, FALSE ) )
7118
d->parseReference_charDataRead = FALSE;
7120
case InAttributeValue:
7121
// Included in literal
7122
if ( !insertXmlRef( it.data(), reference, TRUE ) )
7124
d->parseReference_charDataRead = FALSE;
7130
for ( int i=0; i<(int)reference.length(); i++ ) {
7131
stringAddC( reference[i] );
7134
d->parseReference_charDataRead = TRUE;
7139
d->parseReference_charDataRead = FALSE;
7140
reportParseError( XMLERR_INTERNALGENERALENTITYINDTD );
7144
QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
7145
itExtern = d->externEntities.find( reference );
7146
if ( itExtern == d->externEntities.end() ) {
7147
// entity not declared
7148
// ### check this case for conformance
7149
if ( d->parseReference_context == InEntityValue ) {
7152
for ( int i=0; i<(int)reference.length(); i++ ) {
7153
stringAddC( reference[i] );
7156
d->parseReference_charDataRead = TRUE;
7159
if ( !contentHnd->skippedEntity( reference ) ) {
7160
reportParseError( contentHnd->errorString() );
7161
return FALSE; // error
7165
} else if ( (*itExtern).notation.isNull() ) {
7166
// "External Parsed General"
7167
switch ( d->parseReference_context ) {
7170
// Included if validating
7173
QXmlInputSource *ret = 0;
7174
if ( !entityRes->resolveEntity( itExtern.data().publicId, itExtern.data().systemId, ret ) ) {
7176
reportParseError( entityRes->errorString() );
7180
QString xmlRefString = ret->data();
7182
if ( !stripTextDecl( xmlRefString ) ) {
7183
reportParseError( XMLERR_ERRORINTEXTDECL );
7186
if ( !insertXmlRef( xmlRefString, reference, FALSE ) )
7191
if ( skipIt && contentHnd ) {
7192
if ( !contentHnd->skippedEntity( reference ) ) {
7193
reportParseError( contentHnd->errorString() );
7194
return FALSE; // error
7197
d->parseReference_charDataRead = FALSE;
7199
case InAttributeValue:
7201
d->parseReference_charDataRead = FALSE;
7202
reportParseError( XMLERR_EXTERNALGENERALENTITYINAV );
7208
for ( int i=0; i<(int)reference.length(); i++ ) {
7209
stringAddC( reference[i] );
7212
d->parseReference_charDataRead = TRUE;
7217
d->parseReference_charDataRead = FALSE;
7218
reportParseError( XMLERR_EXTERNALGENERALENTITYINDTD );
7223
// ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
7225
d->parseReference_charDataRead = FALSE;
7226
reportParseError( XMLERR_UNPARSEDENTITYREFERENCE );
7227
return FALSE; // error
7231
return TRUE; // no error
7236
Parses over a simple string.
7238
After the string was successfully parsed, the head is on the first
7239
character after the string.
7241
bool QXmlSimpleReader::parseString()
7243
const signed char InpCharExpected = 0; // the character that was expected
7244
const signed char InpUnknown = 1;
7246
signed char state; // state in this function is the position in the string s
7249
if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
7250
d->Done = d->parseString_s.length();
7253
state = d->parseStack->top()->state;
7254
d->parseStack->remove();
7255
#if defined(QT_QXML_DEBUG)
7256
qDebug( "QXmlSimpleReader: parseString (cont) in state %d", state );
7258
if ( !d->parseStack->isEmpty() ) {
7259
ParseFunction function = d->parseStack->top()->function;
7260
if ( function == &QXmlSimpleReader::eat_ws ) {
7261
d->parseStack->remove();
7262
#if defined(QT_QXML_DEBUG)
7263
qDebug( "QXmlSimpleReader: eat_ws (cont)" );
7266
if ( !(this->*function)() ) {
7267
parseFailed( &QXmlSimpleReader::parseString, state );
7274
if ( state == d->Done ) {
7279
unexpectedEof( &QXmlSimpleReader::parseString, state );
7282
if ( c == d->parseString_s[(int)state] ) {
7283
input = InpCharExpected;
7287
if ( input == InpCharExpected ) {
7291
reportParseError( XMLERR_UNEXPECTEDCHARACTER );
7300
This private function inserts and reports an entity substitution. The
7301
substituted string is \a data and the name of the entity reference is \a
7302
name. If \a inLiteral is TRUE, the entity is IncludedInLiteral (i.e., " and '
7303
must be quoted. Otherwise they are not quoted.
7305
This function returns FALSE on error.
7307
bool QXmlSimpleReader::insertXmlRef( const QString &data, const QString &name, bool inLiteral )
7311
d->xmlRef.push( tmp.replace( "\"", """ ).replace( "'", "'" ) );
7313
d->xmlRef.push( data );
7315
d->xmlRefName.push( name );
7316
uint n = (uint)QMAX( d->parameterEntities.count(), d->entities.count() );
7317
if ( d->xmlRefName.count() > n+1 ) {
7318
// recursive entities
7319
reportParseError( XMLERR_RECURSIVEENTITIES );
7322
if ( d->reportEntities && lexicalHnd ) {
7323
if ( !lexicalHnd->startEntity( name ) ) {
7324
reportParseError( lexicalHnd->errorString() );
7332
This private function moves the cursor to the next character.
7334
void QXmlSimpleReader::next()
7336
int count = (uint)d->xmlRef.count();
7337
while ( count != 0 ) {
7338
if ( d->xmlRef.top().isEmpty() ) {
7339
d->xmlRef.pop_back();
7340
d->xmlRefName.pop_back();
7343
c = d->xmlRef.top().constref( 0 );
7344
d->xmlRef.top().remove( (uint)0, 1 );
7348
// the following could be written nicer, but since it is a time-critical
7349
// function, rather optimize for speed
7351
c = inputSource->next();
7354
} else if ( c == '\r' ) {
7355
c = inputSource->next();
7361
c = inputSource->next();
7367
This private function moves the cursor to the next non-whitespace character.
7368
This function does not move the cursor if the actual cursor position is a
7369
non-whitespace charcter.
7371
Returns FALSE when you use incremental parsing and this function reaches EOF
7372
with reading only whitespace characters. In this case it also poplulates the
7373
parseStack with useful information. In all other cases, this function returns
7376
bool QXmlSimpleReader::eat_ws()
7378
while ( !atEnd() ) {
7384
if ( d->parseStack != 0 ) {
7385
unexpectedEof( &QXmlSimpleReader::eat_ws, 0 );
7391
bool QXmlSimpleReader::next_eat_ws()
7399
This private function initializes the reader. \a i is the input source to
7402
void QXmlSimpleReader::init( const QXmlInputSource *i )
7406
inputSource = (QXmlInputSource *)i;
7409
d->externParameterEntities.clear();
7410
d->parameterEntities.clear();
7411
d->externEntities.clear();
7412
d->entities.clear();
7419
d->standalone = QXmlSimpleReaderPrivate::Unknown;
7420
d->error = QString::null;
7424
This private function initializes the XML data related variables. Especially,
7425
it reads the data from the input source.
7427
void QXmlSimpleReader::initData()
7429
c = QXmlInputSource::EndOfData;
7435
Returns TRUE if a entity with the name \a e exists,
7436
otherwise returns FALSE.
7438
bool QXmlSimpleReader::entityExist( const QString& e ) const
7440
if ( d->parameterEntities.find(e) == d->parameterEntities.end() &&
7441
d->externParameterEntities.find(e) == d->externParameterEntities.end() &&
7442
d->externEntities.find(e) == d->externEntities.end() &&
7443
d->entities.find(e) == d->entities.end() ) {
7450
void QXmlSimpleReader::reportParseError( const QString& error )
7454
if ( d->error.isNull() ) {
7455
errorHnd->fatalError( QXmlParseException( XMLERR_OK, columnNr+1, lineNr+1 ) );
7457
errorHnd->fatalError( QXmlParseException( d->error, columnNr+1, lineNr+1 ) );
7463
This private function is called when a parsing function encounters an
7464
unexpected EOF. It decides what to do (depending on incremental parsing or
7465
not). \a where is a pointer to the function where the error occurred and \a
7466
state is the parsing state in this function.
7468
void QXmlSimpleReader::unexpectedEof( ParseFunction where, int state )
7470
if ( d->parseStack == 0 ) {
7471
reportParseError( XMLERR_UNEXPECTEDEOF );
7473
if ( c == QXmlInputSource::EndOfDocument ) {
7474
reportParseError( XMLERR_UNEXPECTEDEOF );
7476
pushParseState( where, state );
7482
This private function is called when a parse...() function returned FALSE. It
7483
determines if there was an error or if incremental parsing simply went out of
7484
data and does the right thing for the case. \a where is a pointer to the
7485
function where the error occurred and \a state is the parsing state in this
7488
void QXmlSimpleReader::parseFailed( ParseFunction where, int state )
7490
if ( d->parseStack!=0 && d->error.isNull() ) {
7491
pushParseState( where, state );
7496
This private function pushes the function pointer \a function and state \a
7497
state to the parse stack. This is used when you are doing an incremental
7498
parsing and reach the end of file too early.
7500
Only call this function when d->parseStack!=0.
7502
void QXmlSimpleReader::pushParseState( ParseFunction function, int state )
7504
QXmlSimpleReaderPrivate::ParseState *ps = new QXmlSimpleReaderPrivate::ParseState;
7505
ps->function = function;
7507
d->parseStack->push( ps );
7511
// use buffers instead of QString::operator+= when single characters are read
7512
QString& QXmlSimpleReader::string()
7514
stringValue += QString( stringArray, stringPos );
7518
QString& QXmlSimpleReader::name()
7520
nameValue += QString( nameArray, namePos );
7524
QString& QXmlSimpleReader::ref()
7526
refValue += QString( refArray, refPos );
7531
void QXmlSimpleReader::stringAddC()
7533
if ( stringPos >= 256 ) {
7534
stringValue += QString( stringArray, stringPos );
7537
stringArray[stringPos++] = c;
7539
void QXmlSimpleReader::nameAddC()
7541
if ( namePos >= 256 ) {
7542
nameValue += QString( nameArray, namePos );
7545
nameArray[namePos++] = c;
7547
void QXmlSimpleReader::refAddC()
7549
if ( refPos >= 256 ) {
7550
refValue += QString( refArray, refPos );
7553
refArray[refPos++] = c;
7556
void QXmlSimpleReader::stringAddC(const QChar& ch)
7558
if ( stringPos >= 256 ) {
7559
stringValue += QString( stringArray, stringPos );
7562
stringArray[stringPos++] = ch;
7564
void QXmlSimpleReader::nameAddC(const QChar& ch)
7566
if ( namePos >= 256 ) {
7567
nameValue += QString( nameArray, namePos );
7570
nameArray[namePos++] = ch;
7572
void QXmlSimpleReader::refAddC(const QChar& ch)
7574
if ( refPos >= 256 ) {
7575
refValue += QString( refArray, refPos );
7578
refArray[refPos++] = ch;
7581
} // namespace PsiXml