2009-08-13 13 views
10

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

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

(これは解決策が唯一のターゲットXMLによってspeicified DTDに依存するため、Validate XML using a custom DTD in PHPではなく、正しい答えずに頼まれているようだ)

+4

あなたがターゲットXMLにあなたのDTDを追加することができます。あなたのDTDで空のドキュメントを作成し、空のドキュメントにターゲットXMLをロードしてください – rojoca

答えて

16

注:XML validationBillion Laughs攻撃を受ける可能性があり、同様の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に対して文書を検証します。

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

私はこれだけのことをやっていましたので、これがすべてをカバーするかどうかは完全にはわかりませんが、私の例ではXMLには間違いありません。

もちろん、すばやく解決策はXMLを文字列として取得し、元のDTDを検索して自分のDTDで置き換えてからロードすることです。

+0

非常に良い例!どうもありがとうございました。 – Allanrbo

+0

+迅速で汚れたメソッドの場合は+1→検索して置換する。 –

関連する問題