PHP Conference Japan 2024

DOMDocument::validate

(PHP 5, PHP 7, PHP 8)

DOMDocument::validate 根據其 DTD 驗證文件

描述

public DOMDocument::validate(): bool

根據其 DTD 驗證文件。

您也可以使用 DOMDocumentvalidateOnParse 屬性來進行 DTD 驗證。

參數

此函式沒有參數。

傳回值

成功時傳回 true,失敗時傳回 false。如果文件沒有附加 DTD,此方法將傳回 false

範例

範例 #1 DTD 驗證範例

<?php
$dom
= new DOMDocument;
$dom->load('book.xml');
if (
$dom->validate()) {
echo
"此文件有效!\n";
}
?>

您也可以在載入 XML 檔案時驗證它

<?php
$dom
= new DOMDocument;
$dom->validateOnParse = true;
$dom->load('book.xml');
?>

參見

新增註解

使用者貢獻的註解 3 個註解

11
a dot schaffhirt at sedna-soft dot de
16 年前
使用此方法驗證文件時,有兩個我不喜歡的問題。首先,它會產生一堆警告,這是不會預期的,因為呼叫此方法的目的是為了防止在錯誤地依賴文件的有效性時可能發生的任何警告。其次,它只會傳回布林值,而無法取得關於呈現為無效原因的額外詳細資訊。

這就是我使用一個小包裝函式的原因,我將其張貼在這裡,以防有人發現它有用。

請注意,它僅適用於 PHP5 或更新版本。

<?php
class MyDOMDocument {
private
$_delegate;
private
$_validationErrors;

public function
__construct (DOMDocument $pDocument) {
$this->_delegate = $pDocument;
$this->_validationErrors = array();
}

public function
__call ($pMethodName, $pArgs) {
if (
$pMethodName == "validate") {
$eh = set_error_handler(array($this, "onValidateError"));
$rv = $this->_delegate->validate();
if (
$eh) {
set_error_handler($eh);
}
return
$rv;
}
else {
return
call_user_func_array(array($this->_delegate, $pMethodName), $pArgs);
}
}
public function
__get ($pMemberName) {
if (
$pMemberName == "errors") {
return
$this->_validationErrors;
}
else {
return
$this->_delegate->$pMemberName;
}
}
public function
__set ($pMemberName, $pValue) {
$this->_delegate->$pMemberName = $pValue;
}
public function
onValidateError ($pNo, $pString, $pFile = null, $pLine = null, $pContext = null) {
$this->_validationErrors[] = preg_replace("/^.+: */", "", $pString);
}
}
?>

<?php
// $doc 是一個 DOMDocument 物件
$myDoc = new MyDOMDocument($doc); // 複製建構函式

// 使用 $myDoc 執行任何您對 $doc 執行的操作

$isValid = $myDoc->validate(); // 不會產生警告
if (!$isValid) {
print_r($myDoc->errors); // 所有警告都收集在這個陣列中
}
?>

您可能需要變更部分
preg_replace("/^.+: */", "", $pString)
根據您系統的錯誤報告設定(HTML 或純文字)等,變更為其他內容

此致,

安雅
2
cabral dot brc at gmail dot com
14 年前
我試著驗證我的 SVG 檔案,只是為了使用 getElementById() 取得 ID,

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<text id="text_titulo" x="150" y="20" font-family="Arial" font-size="15px" style="font-weight:bold;">標題</text>
<text id="text_subtitulo" x="200" y="35" font-family="Arial" font-size="10px">副標題</text>
<g transform="translate(0,50) scale(0.1)">
<a id="a_AC" ...... >
<polygon id="polygon_AC" ....... />
</a>
</g>
</svg>

但是當呼叫 $dom->load() 時,它會出現錯誤「無法開啟串流」和「驗證失敗:找不到 DTD!I/O 警告:無法載入外部實體」
所以我建立了自己驗證包裝函式(我只是想使用 getElementById() 尋找 ID)

<?php
$docSVG
= new DOMDocument();
$docSVG->load(realpath($filepath));
setAllId($docSVG);


function
setAllId($DOMNode){
if(
$DOMNode->hasChildNodes()){
foreach (
$DOMNode->childNodes as $DOMElement) {
if(
$DOMElement->hasAttributes()){
$id=$DOMElement->getAttribute("id");
if(
$id){
$DOMElement->setIdAttribute("id",$id);
}
}
setAllId($DOMElement);
}
}
}
?>
-6
darren at viamedia dot co dot za
16 年前
如果您載入 XML 的目的是要根據內部 DTD 進行驗證,並且您在驗證時遇到問題,這可能與缺少 LIBXML 常數有關。

我發現「aidan at php dot net」在根層級 dom 文件中的這篇文章,覺得在這裡可能更有用。
從 PHP 5.1 開始,可以使用常數來設定 libxml 選項,而不是使用專有的 DomDocument 屬性。

DomDocument->resolveExternals 等同於設定
LIBXML_DTDLOAD
LIBXML_DTDATTR

DomDocument->validateOnParse 等同於設定
LIBXML_DTDLOAD
LIBXML_DTDVALID

我們鼓勵 PHP 5.1 的使用者使用新的常數。

範例
<?php
$dom
= new DOMDocument;
// 解析外部參照
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDATTR);
// 或
// 根據 DTD 驗證
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDVALID);
$dom->validate();
?>
To Top