PHP Conference Japan 2024

DOMXPath 類別

(PHP 5, PHP 7, PHP 8)

簡介

支援 XPath 1.0

類別概要

class DOMXPath {
/* 屬性 */
public readonly DOMDocument $document;
/* 方法 */
public __construct(DOMDocument $document, bool $registerNodeNS = true)
public evaluate(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed
public query(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed
public static quote(string $str): string
public registerNamespace(string $prefix, string $namespace): bool
}

屬性

document

registerNodeNamespaces

當設定為 true 時,會註冊節點中的命名空間。

變更記錄

版本 說明
8.4.0 不再可能複製 DOMXPath 物件。這樣做會導致拋出例外。在 PHP 8.4.0 之前,這會導致無法使用的物件。
8.0.0 已加入 registerNodeNamespaces 屬性。

目錄

新增筆記

使用者貢獻筆記 5 筆筆記

Mark Omohundro, ajamyajax dot com
15 年前
<?php
// 若要擷取選取的 html 資料,請嘗試以下 DomXPath 範例:

$file = $DOCUMENT_ROOT. "test.html";
$doc = new DOMDocument();
$doc->loadHTMLFile($file);

$xpath = new DOMXpath($doc);

// 範例 1:針對具有 id 的所有項目
//$elements = $xpath->query("//*[@id]");

// 範例 2:針對選取 id 中的節點資料
//$elements = $xpath->query("/html/body/div[@id='yourTagIdHere']");

// 範例 3:與上方相同的項目,但使用萬用字元
$elements = $xpath->query("*/div[@id='yourTagIdHere']");

if (!
is_null($elements)) {
foreach (
$elements as $element) {
echo
"<br/>[". $element->nodeName. "]";

$nodes = $element->childNodes;
foreach (
$nodes as $node) {
echo
$node->nodeValue. "\n";
}
}
}
?>
TechNyquist
4 年前
使用 XML (作為嚴格格式) 時,為 XPath 物件提供命名空間以使其正常運作可能非常重要。

我遇到「query」總是傳回空白節點清單的情況,它找不到任何項目。只有寬廣的「//*」才能顯示根元素。

然後發現,在 XPath 物件中註冊根元素的「xmlns」屬性中回報的命名空間,並在元素名稱附近撰寫命名空間,才能使其正常運作。

因此,針對類似於以下的 XML (來自網站地圖)

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://example.com/index.php</loc>
<lastmod>2005-01-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.5</priority>
</url>
</urlset>

我需要以下的 XPath 設定

<?php

$doc
= new DOMDocument;
$doc->load("sitemap.xml");
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('ns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
$nodes = $xpath->query('//ns:urlset/ns:url');

?>

當然,"xmlns" 也可以從根元素的屬性動態提供。
peter at softcoded dot com
7 年前
您可能無法在執行時總是知道您的檔案是否具有
命名空間。這可能會使建立
XPath 查詢變得困難。請使用嚴重缺乏說明的
DOMDocument 的 documentElement 的 "namespaceURI" 屬性來判斷是否存在命名空間。
DOMDocument 的 documentElement 的 "namespaceURI" 屬性來判斷是否存在命名空間。
使用如下的程式碼

$doc = new DOMDocument();
$doc->load($file);
$xpath = new DOMXPath($doc);
$ns = $doc->documentElement->namespaceURI;
if($ns) {
$xpath->registerNamespace("ns", $ns);
$nodes = $xpath->query("//ns:em[@class='glossterm']");
} else {
$nodes = $xpath->query("//em[@class='glossterm']");
}
// 在這裡查看節點
peter at softcoded dot com
7 年前
使用 XPath 表達式可以節省大量的程式設計
並讓您只專注在您想要的節點上。
假設您想要刪除所有空的 <p> 標籤。
如果您使用以下 XPath 表達式建立查詢,
您可以找到沒有任何文字的 <p> 標籤
(除了空格)、任何屬性、
任何子節點或註解

$expression = "//p[not(@*)
and not(*)
and not(./comment())
and normalize-space(text())='']";

這個表達式只會找到看起來像這樣的段落標籤

<p>[任何數量的空格]</p>
<p></p>

想像一下,如果您使用
DOMDocument::getElementsByTagName("p") 會需要加入多少程式碼。
archimedix32783262 at mailinator dot com
10 年前
請注意,evaluate() 將使用與 XML 文件相同的編碼。

因此,如果您有一個 UTF-16 XML,您將必須使用 UTF-16 字串進行查詢。

您可以使用 iconv() 將程式碼的編碼轉換為目標編碼,以提高可讀性。
To Top