XmlElement* XmlDocument::parseDocumentElement (String::CharPointerType textToParse, const bool onlyReadOuterDocumentElement) { input = textToParse; errorOccurred = false; outOfData = false; needToLoadDTD = true; if (textToParse.isEmpty()) { lastError = "not enough input"; } else if (! parseHeader()) { lastError = "malformed header"; } else if (! parseDTD()) { lastError = "malformed DTD"; } else { lastError.clear(); ScopedPointer<XmlElement> result (readNextElement (! onlyReadOuterDocumentElement)); if (! errorOccurred) return result.release(); } return nullptr; }
void PartialOsmMapReader::readPartial(shared_ptr<OsmMap> map) { _partialMap = map; while (hasMoreElements() && (_elementsRead < _maxElementsPerMap)) { shared_ptr<Element> element = readNextElement(); _partialMap->addElement(element); } _elementsRead = 0; }
/// reads a dictionary QHash<QString, QVariant> BasePListParser::readDict() { QHash<QString, QVariant> result; int level = currentStackLevel(); while( readNextElement("key",level) ) { QString key = readElementText(); QVariant data = readNextPlistType(); result.insert(key,data); } return result; }
/// Start the parsing of the plist. If it isn't a valid plist this method return false. /// (it only checks and reads the existence of <plist>) bool BasePListParser::beginParsing(QIODevice* device) { lastErrorMessage_.clear(); elementStack_.clear(); xml_ = new QXmlStreamReader(device); if( readNextElement("plist" ) ) { return true; } else { raiseError( QObject::tr("Start element not found!")); return false; } }
XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement) { String textToParse (originalText); if (textToParse.isEmpty() && inputSource != nullptr) { ScopedPointer <InputStream> in (inputSource->createInputStream()); if (in != nullptr) { MemoryOutputStream data; data.writeFromInputStream (*in, onlyReadOuterDocumentElement ? 8192 : -1); textToParse = data.toString(); if (! onlyReadOuterDocumentElement) originalText = textToParse; } } input = textToParse.getCharPointer(); lastError = String::empty; errorOccurred = false; outOfData = false; needToLoadDTD = true; if (textToParse.isEmpty()) { lastError = "not enough input"; } else { skipHeader(); if (input.getAddress() != nullptr) { ScopedPointer <XmlElement> result (readNextElement (! onlyReadOuterDocumentElement)); if (! errorOccurred) return result.release(); } else { lastError = "incorrect xml header"; } } return nullptr; }
/// reads the next plist type /// @param level the level we're currently parsing QVariant BasePListParser::readNextPlistType( int level ) { if( readNextElement("",level) ) { // reads a dictionary if( xml_->name().compare( "dict", Qt::CaseInsensitive ) == 0 ) { return readDict(); // reads an array } else if( xml_->name().compare( "array", Qt::CaseInsensitive ) == 0 ) { return readList( ); // reads a string } else if( xml_->name().compare( "string", Qt::CaseInsensitive ) == 0 ) { return readElementText(); } } return QVariant(); }
void XmlDocument::readChildElements (XmlElement& parent) { LinkedListPointer<XmlElement>::Appender childAppender (parent.firstChildElement); for (;;) { const String::CharPointerType preWhitespaceInput (input); skipNextWhiteSpace(); if (outOfData) { setLastError ("unmatched tags", false); break; } if (*input == '<') { const juce_wchar c1 = input[1]; if (c1 == '/') { // our close tag.. const int closeTag = input.indexOf ((juce_wchar) '>'); if (closeTag >= 0) input += closeTag + 1; break; } if (c1 == '!' && CharacterFunctions::compareUpTo (input + 2, CharPointer_ASCII ("[CDATA["), 7) == 0) { input += 9; const String::CharPointerType inputStart (input); for (;;) { const juce_wchar c0 = *input; if (c0 == 0) { setLastError ("unterminated CDATA section", false); outOfData = true; break; } else if (c0 == ']' && input[1] == ']' && input[2] == '>') { childAppender.append (XmlElement::createTextElement (String (inputStart, input))); input += 3; break; } ++input; } } else { // this is some other element, so parse and add it.. if (XmlElement* const n = readNextElement (true)) childAppender.append (n); else break; } } else // must be a character block { input = preWhitespaceInput; // roll back to include the leading whitespace MemoryOutputStream textElementContent; bool contentShouldBeUsed = ! ignoreEmptyTextElements; for (;;) { const juce_wchar c = *input; if (c == '<') { if (input[1] == '!' && input[2] == '-' && input[3] == '-') { input += 4; const int closeComment = input.indexOf (CharPointer_ASCII ("-->")); if (closeComment < 0) { setLastError ("unterminated comment", false); outOfData = true; return; } input += closeComment + 3; continue; } break; } if (c == 0) { setLastError ("unmatched tags", false); outOfData = true; return; } if (c == '&') { String entity; readEntity (entity); if (entity.startsWithChar ('<') && entity [1] != 0) { const String::CharPointerType oldInput (input); const bool oldOutOfData = outOfData; input = entity.getCharPointer(); outOfData = false; while (XmlElement* n = readNextElement (true)) childAppender.append (n); input = oldInput; outOfData = oldOutOfData; } else { textElementContent << entity; contentShouldBeUsed = contentShouldBeUsed || entity.containsNonWhitespaceChars(); } } else { for (;; ++input) { juce_wchar nextChar = *input; if (nextChar == '\r') { nextChar = '\n'; if (input[1] == '\n') continue; } if (nextChar == '<' || nextChar == '&') break; if (nextChar == 0) { setLastError ("unmatched tags", false); outOfData = true; return; } textElementContent.appendUTF8Char (nextChar); contentShouldBeUsed = contentShouldBeUsed || ! CharacterFunctions::isWhitespace (nextChar); } } } if (contentShouldBeUsed) childAppender.append (XmlElement::createTextElement (textElementContent.toUTF8())); } } }
void XmlDocument::readChildElements (XmlElement* parent) { LinkedListPointer<XmlElement>::Appender childAppender (parent->firstChildElement); for (;;) { const String::CharPointerType preWhitespaceInput (input); skipNextWhiteSpace(); if (outOfData) { setLastError ("unmatched tags", false); break; } if (*input == '<') { if (input[1] == '/') { // our close tag.. const int closeTag = input.indexOf ((juce_wchar) '>'); if (closeTag >= 0) input += closeTag + 1; break; } else if (input[1] == '!' && input[2] == '[' && input[3] == 'C' && input[4] == 'D' && input[5] == 'A' && input[6] == 'T' && input[7] == 'A' && input[8] == '[') { input += 9; const String::CharPointerType inputStart (input); size_t len = 0; for (;;) { if (*input == 0) { setLastError ("unterminated CDATA section", false); outOfData = true; break; } else if (input[0] == ']' && input[1] == ']' && input[2] == '>') { input += 3; break; } ++input; ++len; } childAppender.append (XmlElement::createTextElement (String (inputStart, len))); } else { // this is some other element, so parse and add it.. if (XmlElement* const n = readNextElement (true)) childAppender.append (n); else break; } } else // must be a character block { input = preWhitespaceInput; // roll back to include the leading whitespace String textElementContent; for (;;) { const juce_wchar c = *input; if (c == '<') break; if (c == 0) { setLastError ("unmatched tags", false); outOfData = true; return; } if (c == '&') { String entity; readEntity (entity); if (entity.startsWithChar ('<') && entity [1] != 0) { const String::CharPointerType oldInput (input); const bool oldOutOfData = outOfData; input = entity.getCharPointer(); outOfData = false; for (;;) { XmlElement* const n = readNextElement (true); if (n == nullptr) break; childAppender.append (n); } input = oldInput; outOfData = oldOutOfData; } else { textElementContent += entity; } } else { const String::CharPointerType start (input); size_t len = 0; for (;;) { const juce_wchar nextChar = *input; if (nextChar == '<' || nextChar == '&') { break; } else if (nextChar == 0) { setLastError ("unmatched tags", false); outOfData = true; return; } ++input; ++len; } textElementContent.appendCharPointer (start, len); } } if ((! ignoreEmptyTextElements) || textElementContent.containsNonWhitespaceChars()) { childAppender.append (XmlElement::createTextElement (textElementContent)); } } } }