10

PHPでは、外部でフェッチされたXMLドキュメントではなく、アプリケーションで指定されたDTDを使用してXMLドキュメントを検証しようとしています。DOMDocumentクラスのvalidateメソッドは、XMLドキュメント自体で指定されたDTDを使用してのみ検証するように見えるため、これは機能しません。

これを行うことはできますか?また、schemaValidateメソッドを使用できるようにDTDをXMLスキーマに変換する必要がありますか?

(これは、PHPのカスタムDTDを使用してXMLを検証する際に求められたようですが、ソリューションはターゲットXMLによって指定されたDTDのみに依存しているため、正解はありません)

4

2 に答える 2

17

注:XML検証は、 BillionLaughs攻撃や同様のDoSベクトルの影響を受ける可能性があります。

これは基本的に、rojocaが彼のコメントで述べたことを実行します。

<?php

$xml = <<<END
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo SYSTEM "foo.dtd">
<foo>
    <bar>baz</bar>
</foo>
END;

$root = 'foo';

$old = new DOMDocument;
$old->loadXML($xml);

$creator = new DOMImplementation;
$doctype = $creator->createDocumentType($root, null, 'bar.dtd');
$new = $creator->createDocument(null, null, $doctype);
$new->encoding = "utf-8";

$oldNode = $old->getElementsByTagName($root)->item(0);
$newNode = $new->importNode($oldNode, true);
$new->appendChild($newNode);

$new->validate();

?>

これにより、ドキュメントがに対して検証されますbar.dtd

を呼び出すことはできません$new->loadXML()。これは、DTDを元のオブジェクトに設定するだけdoctypeであり、DOMDocumentオブジェクトのプロパティは読み取り専用であるため、ルートノード(すべてを含む)を新しいDOMドキュメントにコピーする必要があります。

私はこれを自分で試してみただけなので、これがすべてをカバーしているかどうかは完全にはわかりませんが、私の例のXMLでは間違いなく機能します。

もちろん、手っ取り早い解決策は、最初にXMLを文字列として取得し、元のDTDを検索して独自のDTDに置き換えてから、それをロードすることです。

于 2009-08-13T22:08:04.147 に答える
1

これはXSDでのみ可能だと思います。http:
//php.net/manual/en/domdocument.schemavalidate#62032を参照してください。

于 2009-08-23T19:30:28.413 に答える