2009-08-13 81 views
10

在PHP中,我試圖使用由我的應用程序指定的DTD來驗證XML文檔 - 而不是從外部提取的XML文檔。 DOMDocument類中的validate方法似乎只使用XML文檔本身指定的DTD進行驗證,所以這不起作用。對PHP中給定的DTD進行XML驗證

可以這樣做,以及如何或者我必須將我的DTD轉換爲XML模式,以便我可以使用schemaValidate方法?

(這似乎已在Validate XML using a custom DTD in PHP但沒有正確的答案被要求,因爲該解決方案唯一依賴於DTD的目標XML speicified)

+4

你能你的DTD添加到目標XML。用你的DTD創建一個空文檔,然後將你的目標XML加載到空文檔中 – rojoca 2009-08-13 20:43:04

回答

16

注:XML validation可能是受Billion 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文檔。

你不能只是叫$new->loadXML(),因爲那會剛剛成立的DTD原來的,和DOMDocument對象的doctype屬性是隻讀的,所以你必須複製根節點(與它的一切)到一個新的DOM文檔。

我只是剛剛與這個我自己去,所以我不完全確定這是否涵蓋了所有內容,但它在我的示例中絕對適用於XML。

當然,快速和骯髒的解決方案是首先將XML作爲字符串獲取,然後通過自己的DTD搜索並替換原始的DTD,然後加載它。

+0

非常好的例子!非常感謝你。 – Allanrbo 2009-08-16 07:55:07

+0

+1爲快速和骯髒的方法 - >搜索和替換。 – 2013-04-05 18:15:15