Чтение и проверка XML-документа с внешними объектами с использованием Qt

Я пытаюсь прочитать и проверить документ XML, который имеет внешние объекты. Но у меня нет успеха ни с чтением, ни с проверкой. Я использовал это, чтобы создать тестовый пример.

Тест XML:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE doc [
<!ENTITY otherFile SYSTEM "otherFile.xml">
]>
<doc>&otherFile;</doc>

Другое xml:

<baz>this is my content</baz>

Тест XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="doc">
    <xs:complexType>
    <xs:sequence>
      <xs:element ref="baz"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="baz" type="xs:string"/>

</xs:schema>

Сначала я пытаюсь прочитать содержимое test.xml, используя QDomDocument:

QDomDocument doc;
doc.setContent(&testFile);
qDebug() << doc.toString();

Но в результате отладки я получаю необработанный текст из test.xml. Внешний объект не замещен.

Затем я пытаюсь проверить test.xml по сравнению с test.xsd:

QXmlSchema schema;
bool res = schema.load(&xsdFile, QUrl::fromLocalFile(xsdPath));
if (res == true)
{
    QXmlSchemaValidator validator(schema);
    if (validator.validate(&xmlFile, QUrl::fromLocalFile(xmlPath)))
    {
        qDebug() << "xml" << xmlName << "is valid";
    }
    else
    {
    qDebug() << "xml" << xmlName << "is invalid";
    }
}

Но проверка не проходит, и я получаю следующую ошибку:

Error XSDError in file:///..., at line 5, column 5: Element doc is missing child element.

Я делаю что-то не так или модуль Qt Xml просто не поддерживает внешние объекты?

1 ответ

Решение

Я рассмотрел это для вас, и короткий ответ заключается в том, что, возможно, вам придется перейти на использование другого анализатора и валидатора, если вам нужна поддержка сущностей DTD SYSTEM.

Qt 4 имеет три разных анализатора XML:

  • QXmlStreamReader - Вытащите парсер, часть QtCore, теперь рекомендуемый парсер
  • QXmlSimpleReader - Анализатор push (событий), часть QtXML
  • QDomDocument - DOM-парсер, часть QtXML

Было решено, что иметь 3 различных типа анализатора слишком сложно, поэтому с переходом на Qt 5 модуль XML устарел, и теперь рекомендуемым анализатором является QXmlStreamReader. Это довольно простой в использовании синтаксический анализатор (в отличие от QXmlSimpleReader), но он использует намного меньше памяти, чем QDomDocument.

Поэтому, если вы пишете новый код в Qt для разбора XML, даже если вы в настоящее время не используете Qt 5, я настоятельно рекомендую использовать QXmlStreamReader.

К сожалению для вас, страница руководства отмечает:

QXmlStreamReader - это правильно сформированный синтаксический анализатор XML 1.0, который не включает внешние анализируемые объекты.

Это означает, что это не решает ваши СИСТЕМНЫЕ сущности. Кроме того, после проверки исходного кода не похоже, что существуют какие-либо "скрытые" ловушки или методы, которые можно использовать для перехвата разрешения объекта.

Если вы хотите включить внешние XML-документы в другой документ, вы можете посмотреть, используя XInclude. Было бы достаточно просто написать процессор XInclude, используя QXmlStreamReader и QXmlStreamWriter.

Вот базовый процессор Qt XInclude, который я написал, он включает только один уровень включения, но я уверен, что вы могли бы расширить его для поддержки рекурсивного включения достаточно легко.

Получив полностью разрешенный XML-документ, вы сможете использовать QXmlSchemaValidator для его проверки.

Другие вопросы по тегам