Чтение и проверка 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 просто не поддерживает внешние объекты?


person hank    schedule 19.09.2013    source источник


Ответы (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, который не включает внешние анализируемые сущности.

Это означает, что он не разрешает ваши сущности SYSTEM. Кроме того, после проверки исходного кода не похоже, что есть какие-либо «скрытые» хуки или методы, которые можно использовать для перехвата разрешения объекта.

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

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

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

person Silas Parker    schedule 29.09.2013
comment
Спасибо за ваш ответ. Изначально у меня была идея вручную собрать полный xml, но я не думал, что это будет очень элегантно, и я надеялся, что есть какое-то готовое решение. Но теперь у меня есть уверенность, что я пойду по этому пути. - person hank; 30.09.2013