3

外部エンティティを持つ 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.xsd に対して test.xml を検証しようとします。

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 モジュールが外部エンティティをサポートしていないだけですか?

4

1 に答える 1

4

私はあなたのためにこれを調べました。短い答えは、DTD SYSTEM エンティティのサポートが必要な場合は、別のパーサーとバリデーターを使用するように変更する必要があるかもしれないということです。

Qt 4 には 3 つの異なる XML パーサーがあります。

  • QXmlStreamReader- QtCore の一部であるプル パーサーが推奨されるパーサーになりました
  • QXmlSimpleReader- プッシュ (イベント) パーサー、QtXML の一部
  • QDomDocument- DOM パーサー、QtXML の一部

3 種類のパーサーを使用するのは複雑すぎると判断されたため、Qt 5 への移行に伴い、XML モジュールは廃止され、推奨されるパーサーはQXmlStreamReaderになりました。これは ( QXmlSimpleReaderとは異なり) 非常に使いやすいパーサーですが、 QDomDocumentよりもメモリ使用量がはるかに少なくなります。

したがって、XML 解析のために Qt で新しいコードを作成している場合は、現在 Qt 5 を使用していなくても、QXmlStreamReaderを使用することを強くお勧めします。

残念ながら、マニュアルページには次のように記載されています。

QXmlStreamReader は整形式の XML 1.0 パーサーであり、外部の解析対象エンティティは含まれません。

つまり、SYSTEM エンティティは解決されません。また、ソース コードを調べたところ、エンティティの解決を傍受するために使用できる「隠し」フックやメソッドがないように見えます。

外部の XML ドキュメントを別のドキュメントに含めたい場合は、XIncludeの使用を検討することをお勧めします。QXmlStreamReaderQXmlStreamWriterを使用して XInclude プロセッサを作成するのはかなり簡単です。

これは私が書いた基本的な Qt XInclude プロセッサです。これは 1 レベルのインクルードしか行いませんが、再帰的なインクルードを合理的に簡単にサポートするように拡張できると確信しています。

完全に解決された XML ドキュメントを取得したら、 QXmlSchemaValidatorを使用してそれを検証できるはずです。

于 2013-09-29T20:06:15.847 に答える