📄 qxml.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtXML module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qxml.h"#include "qtextcodec.h"#include "qbuffer.h"#include "qregexp.h"#include "qmap.h"#include "qstack.h"#include <qdebug.h>#ifdef Q_CC_BOR // borland 6 finds bogus warnings when building this file in uic3# pragma warn -8080#endif//#define QT_QXML_DEBUG// Error strings for the XML reader#define XMLERR_OK QT_TRANSLATE_NOOP("QXml", "no error occurred")#define XMLERR_ERRORBYCONSUMER QT_TRANSLATE_NOOP("QXml", "error triggered by consumer")#define XMLERR_UNEXPECTEDEOF QT_TRANSLATE_NOOP("QXml", "unexpected end of file")#define XMLERR_MORETHANONEDOCTYPE QT_TRANSLATE_NOOP("QXml", "more than one document type definition")#define XMLERR_ERRORPARSINGELEMENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing element")#define XMLERR_TAGMISMATCH QT_TRANSLATE_NOOP("QXml", "tag mismatch")#define XMLERR_ERRORPARSINGCONTENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing content")#define XMLERR_UNEXPECTEDCHARACTER QT_TRANSLATE_NOOP("QXml", "unexpected character")#define XMLERR_INVALIDNAMEFORPI QT_TRANSLATE_NOOP("QXml", "invalid name for processing instruction")#define XMLERR_VERSIONEXPECTED QT_TRANSLATE_NOOP("QXml", "version expected while reading the XML declaration")#define XMLERR_WRONGVALUEFORSDECL QT_TRANSLATE_NOOP("QXml", "wrong value for standalone declaration")#define XMLERR_EDECLORSDDECLEXPECTED QT_TRANSLATE_NOOP("QXml", "encoding declaration or standalone declaration expected while reading the XML declaration")#define XMLERR_SDDECLEXPECTED QT_TRANSLATE_NOOP("QXml", "standalone declaration expected while reading the XML declaration")#define XMLERR_ERRORPARSINGDOCTYPE QT_TRANSLATE_NOOP("QXml", "error occurred while parsing document type definition")#define XMLERR_LETTEREXPECTED QT_TRANSLATE_NOOP("QXml", "letter is expected")#define XMLERR_ERRORPARSINGCOMMENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing comment")#define XMLERR_ERRORPARSINGREFERENCE QT_TRANSLATE_NOOP("QXml", "error occurred while parsing reference")#define XMLERR_INTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "internal general entity reference not allowed in DTD")#define XMLERR_EXTERNALGENERALENTITYINAV QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in attribute value")#define XMLERR_EXTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in DTD")#define XMLERR_UNPARSEDENTITYREFERENCE QT_TRANSLATE_NOOP("QXml", "unparsed entity reference in wrong context")#define XMLERR_RECURSIVEENTITIES QT_TRANSLATE_NOOP("QXml", "recursive entities")#define XMLERR_ERRORINTEXTDECL QT_TRANSLATE_NOOP("QXml", "error in the text declaration of an external entity")// the constants for the lookup tablestatic const signed char cltWS = 0; // white spacestatic const signed char cltPer = 1; // %static const signed char cltAmp = 2; // &static const signed char cltGt = 3; // >static const signed char cltLt = 4; // <static const signed char cltSlash = 5; // /static const signed char cltQm = 6; // ?static const signed char cltEm = 7; // !static const signed char cltDash = 8; // -static const signed char cltCB = 9; // ]static const signed char cltOB = 10; // [static const signed char cltEq = 11; // =static const signed char cltDq = 12; // "static const signed char cltSq = 13; // 'static const signed char cltUnknown = 14;// Hack for letting QDom know where the skipped entity occurredbool qt_xml_skipped_entity_in_content;// character lookup tablestatic const signed char charLookupTable[256]={ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07 cltUnknown, // 0x08 cltWS, // 0x09 \t cltWS, // 0x0A \n cltUnknown, // 0x0B cltUnknown, // 0x0C cltWS, // 0x0D \r cltUnknown, // 0x0E cltUnknown, // 0x0F cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F cltWS, // 0x20 Space cltEm, // 0x21 ! cltDq, // 0x22 " cltUnknown, // 0x23 cltUnknown, // 0x24 cltPer, // 0x25 % cltAmp, // 0x26 & cltSq, // 0x27 ' cltUnknown, // 0x28 cltUnknown, // 0x29 cltUnknown, // 0x2A cltUnknown, // 0x2B cltUnknown, // 0x2C cltDash, // 0x2D - cltUnknown, // 0x2E cltSlash, // 0x2F / cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37 cltUnknown, // 0x38 cltUnknown, // 0x39 cltUnknown, // 0x3A cltUnknown, // 0x3B cltLt, // 0x3C < cltEq, // 0x3D = cltGt, // 0x3E > cltQm, // 0x3F ? cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57 cltUnknown, // 0x58 cltUnknown, // 0x59 cltUnknown, // 0x5A cltOB, // 0x5B [ cltUnknown, // 0x5C cltCB, // 0x5D] cltUnknown, // 0x5E cltUnknown, // 0x5F cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7 cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF};//// local helper functions///* This function strips the TextDecl [77] ("<?xml ...?>") from the string \a str. The stripped version is stored in \a str. If this function finds an invalid TextDecl, it returns false, otherwise true. This function is used for external entities since those can include an TextDecl that must be stripped before inserting the entity.*/static bool stripTextDecl(QString& str){ QString textDeclStart(QLatin1String("<?xml")); if (str.startsWith(textDeclStart)) { QRegExp textDecl(QString::fromLatin1( "^<\\?xml\\s+" "(version\\s*=\\s*((['\"])[-a-zA-Z0-9_.:]+\\3))?" "\\s*" "(encoding\\s*=\\s*((['\"])[A-Za-z][-a-zA-Z0-9_.]*\\6))?" "\\s*\\?>" )); QString strTmp = str.replace(textDecl, QLatin1String("")); if (strTmp.length() != str.length()) return false; // external entity has wrong TextDecl str = strTmp; } return true;}class QXmlAttributesPrivate{};/* \class QXmlInputSourcePrivate \internal There's a slight misdesign in this class that can be worth to keep in mind: the `str' member is a buffer which QXmlInputSource::next() returns from, and which is populated from the input device or input stream. However, when the input is a QString(the user called QXmlInputSource::setData()), `str' has two roles: it's the buffer, but also the source. This /seems/ to be no problem because in the case of having no device or stream, the QString is read in one go. */class QXmlInputSourcePrivate{public: QIODevice *inputDevice; QTextStream *inputStream; QString str; const QChar *unicode; int pos; int length; bool nextReturnedEndOfData;#ifndef QT_NO_TEXTCODEC QTextDecoder *encMapper;#endif QByteArray encodingDeclBytes; QString encodingDeclChars; bool lookingForEncodingDecl;};class QXmlParseExceptionPrivate{public: QString msg; int column; int line; QString pub; QString sys;};class QXmlLocatorPrivate{};class QXmlDefaultHandlerPrivate{};class QXmlSimpleReaderPrivate{private: // functions QXmlSimpleReaderPrivate(); ~QXmlSimpleReaderPrivate(); void initIncrementalParsing(); // used to determine if elements are correctly nested QStack<QString> tags; // used by parseReference() and parsePEReference() enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD }; // used for entity declarations struct ExternParameterEntity { ExternParameterEntity() {} ExternParameterEntity(const QString &p, const QString &s) : publicId(p), systemId(s) {} QString publicId; QString systemId; Q_DUMMY_COMPARISON_OPERATOR(ExternParameterEntity) }; struct ExternEntity { ExternEntity() {} ExternEntity(const QString &p, const QString &s, const QString &n) : publicId(p), systemId(s), notation(n) {} QString publicId; QString systemId; QString notation; Q_DUMMY_COMPARISON_OPERATOR(ExternEntity) }; QMap<QString,ExternParameterEntity> externParameterEntities; QMap<QString,QString> parameterEntities; QMap<QString,ExternEntity> externEntities; QMap<QString,QString> entities; // used for parsing of entity references struct XmlRef { XmlRef(const QString &_name = QString(), const QString &_value = QString()) : name(_name), value(_value), index(0) {} bool isEmpty() const { return index == value.length(); } QChar next() { return value.at(index++); } QString name; QString value; int index; }; QStack<XmlRef> xmlRefStack; // used for standalone declaration enum Standalone { Yes, No, Unknown }; QString doctype; // only used for the doctype QString xmlVersion; // only used to store the version information QString encoding; // only used to store the encoding Standalone standalone; // used to store the value of the standalone declaration QString publicId; // used by parseExternalID() to store the public ID QString systemId; // used by parseExternalID() to store the system ID // Since publicId/systemId is used as temporary variables by parseExternalID(), it // might overwrite the PUBLIC/SYSTEM for the document we're parsing. In effect, we would // possibly send off an QXmlParseException that has the PUBLIC/SYSTEM of a entity declaration // instead of those of the current document. // Hence we have these two variables for storing the document's data. QString thisPublicId; QString thisSystemId; QString attDeclEName; // use by parseAttlistDecl() QString attDeclAName; // use by parseAttlistDecl() // flags for some features support bool useNamespaces; bool useNamespacePrefixes; bool reportWhitespaceCharData; bool reportEntities; // used to build the attribute list QXmlAttributes attList; // used in QXmlSimpleReader::parseContent() to decide whether character // data was read bool contentCharDataRead; // helper classes QXmlLocator *locator; QXmlNamespaceSupport namespaceSupport; // error string QString error; // arguments for parse functions (this is needed to allow incremental // parsing) bool parsePI_xmldecl; bool parseName_useRef; bool parseReference_charDataRead; EntityRecognitionContext parseReference_context; bool parseExternalID_allowPublicID; EntityRecognitionContext parsePEReference_context; QString parseString_s; // for incremental parsing struct ParseState { typedef bool (QXmlSimpleReaderPrivate::*ParseFunction)(); ParseFunction function; int state; }; QStack<ParseState> *parseStack; // used in parseProlog() bool xmldecl_possible; bool doctype_read; // used in parseDoctype() bool startDTDwasReported; // used in parseString() signed char Done; // variables QXmlContentHandler *contentHnd; QXmlErrorHandler *errorHnd; QXmlDTDHandler *dtdHnd; QXmlEntityResolver *entityRes; QXmlLexicalHandler *lexicalHnd; QXmlDeclHandler *declHnd; QXmlInputSource *inputSource; QChar c; // the character at reading position int lineNr; // number of line int columnNr; // position in line QChar nameArray[256]; // only used for names QString nameValue; // only used for names int nameArrayPos; int nameValueLen; QChar refArray[256]; // only used for references QString refValue; // only used for references int refArrayPos; int refValueLen; QChar stringArray[256]; // used for any other strings that are parsed QString stringValue; // used for any other strings that are parsed int stringArrayPos; int stringValueLen; QString emptyStr; const QString &string(); void stringClear(); void stringAddC(QChar); inline void stringAddC() { stringAddC(c); } const QString &name(); void nameClear(); void nameAddC(QChar); inline void nameAddC() { nameAddC(c); } const QString &ref(); void refClear(); void refAddC(QChar); inline void refAddC() { refAddC(c); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -