📄 xmltokenizerqt.cpp
字号:
if (ec) // exception setting attributes return; }}static inline void handleElementAttributes(Element* newElement, const QXmlStreamAttributes &attrs, ExceptionCode& ec){ for (int i = 0; i < attrs.count(); ++i) { const QXmlStreamAttribute &attr = attrs[i]; String attrLocalName = attr.name(); String attrValue = attr.value(); String attrURI = attr.namespaceUri().isEmpty() ? String() : String(attr.namespaceUri()); String attrQName = attr.qualifiedName(); newElement->setAttributeNS(attrURI, attrQName, attrValue, ec); if (ec) // exception setting attributes return; }}void XMLTokenizer::parse(){ while (!m_parserStopped && !m_parserPaused && !m_stream.atEnd()) { m_stream.readNext(); switch (m_stream.tokenType()) { case QXmlStreamReader::StartDocument: { startDocument(); } break; case QXmlStreamReader::EndDocument: { endDocument(); } break; case QXmlStreamReader::StartElement: { parseStartElement(); } break; case QXmlStreamReader::EndElement: { parseEndElement(); } break; case QXmlStreamReader::Characters: { if (m_stream.isCDATA()) { //cdata parseCdata(); } else { //characters parseCharacters(); } } break; case QXmlStreamReader::Comment: { parseComment(); } break; case QXmlStreamReader::DTD: { //qDebug()<<"------------- DTD"; parseDtd(); } break; case QXmlStreamReader::EntityReference: { //qDebug()<<"---------- ENTITY = "<<m_stream.name().toString() // <<", t = "<<m_stream.text().toString(); if (isXHTMLDocument()#if ENABLE(WML) || isWMLDocument()#endif ) { QString entity = m_stream.name().toString(); UChar c = decodeNamedEntity(entity.toUtf8().constData()); if (m_currentNode->isTextNode() || enterText()) { ExceptionCode ec = 0; String str(&c, 1); //qDebug()<<" ------- adding entity "<<str; static_cast<Text*>(m_currentNode)->appendData(str, ec); } } } break; case QXmlStreamReader::ProcessingInstruction: { parseProcessingInstruction(); } break; default: { if (m_stream.error() != QXmlStreamReader::PrematureEndOfDocumentError) { ErrorType type = (m_stream.error() == QXmlStreamReader::NotWellFormedError) ? fatal : warning; handleError(type, qPrintable(m_stream.errorString()), lineNumber(), columnNumber()); } } break; } }}void XMLTokenizer::startDocument(){ initializeParserContext(); ExceptionCode ec = 0; if (!m_parsingFragment) { m_doc->setXMLStandalone(m_stream.isStandaloneDocument(), ec);#if QT_VERSION >= 0x040400 QStringRef version = m_stream.documentVersion(); if (!version.isEmpty()) m_doc->setXMLVersion(version, ec); QStringRef encoding = m_stream.documentEncoding(); if (!encoding.isEmpty()) m_doc->setXMLEncoding(encoding);#endif }}void XMLTokenizer::parseStartElement(){ if (!m_sawFirstElement && m_parsingFragment) { // skip dummy element for fragments m_sawFirstElement = true; return; } bool isFirstElement = !m_sawFirstElement; m_sawFirstElement = true; exitText(); String localName = m_stream.name(); String uri = m_stream.namespaceUri(); String prefix = prefixFromQName(m_stream.qualifiedName().toString()); if (m_parsingFragment && uri.isNull()) { Q_ASSERT (prefix.isNull()); uri = m_defaultNamespaceURI; } QualifiedName qName(prefix, localName, uri); RefPtr<Element> newElement = m_doc->createElement(qName, true); if (!newElement) { stopParsing(); return; } ExceptionCode ec = 0; handleElementNamespaces(newElement.get(), m_stream.namespaceDeclarations(), ec); if (ec) { stopParsing(); return; } handleElementAttributes(newElement.get(), m_stream.attributes(), ec); if (ec) { stopParsing(); return; } ScriptElement* scriptElement = toScriptElement(newElement.get()); if (scriptElement) m_scriptStartLine = lineNumber(); if (!m_currentNode->addChild(newElement.get())) { stopParsing(); return; } setCurrentNode(newElement.get()); if (m_view && !newElement->attached()) newElement->attach(); if (isFirstElement && m_doc->frame()) m_doc->frame()->loader()->dispatchDocumentElementAvailable();}void XMLTokenizer::parseEndElement(){ exitText(); Node* n = m_currentNode; RefPtr<Node> parent = n->parentNode(); n->finishParsingChildren(); if (!n->isElementNode() || !m_view) { setCurrentNode(parent.get()); return; } Element* element = static_cast<Element*>(n); ScriptElement* scriptElement = toScriptElement(element); if (!scriptElement) { setCurrentNode(parent.get()); return; } // don't load external scripts for standalone documents (for now) ASSERT(!m_pendingScript); m_requestingScript = true; String scriptHref = scriptElement->sourceAttributeValue(); if (!scriptHref.isEmpty()) { // we have a src attribute String scriptCharset = scriptElement->scriptCharset(); if ((m_pendingScript = m_doc->docLoader()->requestScript(scriptHref, scriptCharset))) { m_scriptElement = element; m_pendingScript->addClient(this); // m_pendingScript will be 0 if script was already loaded and ref() executed it if (m_pendingScript) pauseParsing(); } else m_scriptElement = 0; } else m_view->frame()->loader()->executeScript(ScriptSourceCode(scriptElement->scriptContent(), m_doc->url(), m_scriptStartLine)); m_requestingScript = false; setCurrentNode(parent.get());}void XMLTokenizer::parseCharacters(){ if (m_currentNode->isTextNode() || enterText()) { ExceptionCode ec = 0; static_cast<Text*>(m_currentNode)->appendData(m_stream.text(), ec); }}void XMLTokenizer::parseProcessingInstruction(){ exitText(); // ### handle exceptions int exception = 0; RefPtr<ProcessingInstruction> pi = m_doc->createProcessingInstruction( m_stream.processingInstructionTarget(), m_stream.processingInstructionData(), exception); if (exception) return; pi->setCreatedByParser(true); if (!m_currentNode->addChild(pi.get())) return; if (m_view && !pi->attached()) pi->attach(); pi->finishParsingChildren();#if ENABLE(XSLT) m_sawXSLTransform = !m_sawFirstElement && pi->isXSL(); if (m_sawXSLTransform && !m_doc->transformSourceDocument())) stopParsing();#endif}void XMLTokenizer::parseCdata(){ exitText(); RefPtr<Node> newNode = new CDATASection(m_doc, m_stream.text()); if (!m_currentNode->addChild(newNode.get())) return; if (m_view && !newNode->attached()) newNode->attach();}void XMLTokenizer::parseComment(){ exitText(); RefPtr<Node> newNode = new Comment(m_doc, m_stream.text()); m_currentNode->addChild(newNode.get()); if (m_view && !newNode->attached()) newNode->attach();}void XMLTokenizer::endDocument(){}bool XMLTokenizer::hasError() const{ return m_stream.hasError();}#if QT_VERSION < 0x040400static QString parseId(const QString &dtd, int *pos, bool *ok){ *ok = true; int start = *pos + 1; int end = start; if (dtd.at(*pos) == QLatin1Char('\'')) while (start < dtd.length() && dtd.at(end) != QLatin1Char('\'')) ++end; else if (dtd.at(*pos) == QLatin1Char('\"')) while (start < dtd.length() && dtd.at(end) != QLatin1Char('\"')) ++end; else { *ok = false; return QString(); } *pos = end + 1; return dtd.mid(start, end - start);}#endifvoid XMLTokenizer::parseDtd(){#if QT_VERSION >= 0x040400 QStringRef name = m_stream.dtdName(); QStringRef publicId = m_stream.dtdPublicId(); QStringRef systemId = m_stream.dtdSystemId();#else QString dtd = m_stream.text().toString(); int start = dtd.indexOf("<!DOCTYPE ") + 10; while (start < dtd.length() && dtd.at(start).isSpace()) ++start; int end = start; while (start < dtd.length() && !dtd.at(end).isSpace()) ++end; QString name = dtd.mid(start, end - start); start = end; while (start < dtd.length() && dtd.at(start).isSpace()) ++start; end = start; while (start < dtd.length() && !dtd.at(end).isSpace()) ++end; QString id = dtd.mid(start, end - start); start = end; while (start < dtd.length() && dtd.at(start).isSpace()) ++start; QString publicId; QString systemId; if (id == QLatin1String("PUBLIC")) { bool ok; publicId = parseId(dtd, &start, &ok); if (!ok) { handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber()); return; } while (start < dtd.length() && dtd.at(start).isSpace()) ++start; systemId = parseId(dtd, &start, &ok); if (!ok) { handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber()); return; } } else if (id == QLatin1String("SYSTEM")) { bool ok; systemId = parseId(dtd, &start, &ok); if (!ok) { handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber()); return; } } else if (id == QLatin1String("[") || id == QLatin1String(">")) { } else { handleError(fatal, "Invalid DOCTYPE", lineNumber(), columnNumber()); return; }#endif //qDebug() << dtd << name << publicId << systemId; if ((publicId == QLatin1String("-//W3C//DTD XHTML 1.0 Transitional//EN")) || (publicId == QLatin1String("-//W3C//DTD XHTML 1.1//EN")) || (publicId == QLatin1String("-//W3C//DTD XHTML 1.0 Strict//EN")) || (publicId == QLatin1String("-//W3C//DTD XHTML 1.0 Frameset//EN")) || (publicId == QLatin1String("-//W3C//DTD XHTML Basic 1.0//EN")) || (publicId == QLatin1String("-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN")) || (publicId == QLatin1String("-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN")) || (publicId == QLatin1String("-//WAPFORUM//DTD XHTML Mobile 1.0//EN"))) { setIsXHTMLDocument(true); // controls if we replace entities or not. }#if ENABLE(WML) else if (m_doc->isWMLDocument() && publicId != QLatin1String("-//WAPFORUM//DTD WML 1.3//EN") && publicId != QLatin1String("-//WAPFORUM//DTD WML 1.2//EN") && publicId != QLatin1String("-//WAPFORUM//DTD WML 1.1//EN") && publicId != QLatin1String("-//WAPFORUM//DTD WML 1.0//EN")) handleError(fatal, "Invalid DTD Public ID", lineNumber(), columnNumber());#endif if (!m_parsingFragment) m_doc->addChild(DocumentType::create(m_doc, name, publicId, systemId)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -