目录
什么是 XPath,它如何在 PHP DOM 中使用?
如何创建 DOMXPath 的实例?
如何使用 XPath 选择节点?
DOMXPath 中 query()evaluate() 方法的区别是什么?
如何在 XPath 查询中处理命名空间?
如何使用 XPath 选择属性?
如何在 PHP DOM 中使用 XPath 函数?
我可以在 PHP DOM 中将 XPath 与 HTML 文档一起使用吗?
如何在 PHP DOM 中使用 XPath 时处理错误?
我可以使用 PHP DOM 中的 XPath 修改 XML 文档吗?
首页 后端开发 php教程 PHP DOM:使用XPATH

PHP DOM:使用XPATH

Feb 26, 2025 am 09:07 AM

PHP DOM: Using XPath

核心要点

  • XPath 是一种用于查询 XML 文档的语法,它提供了一种更简单、更简洁的方式来编写功能,并减少了编写查询和过滤 XML 数据所需的代码量。
  • XPath 查询可以使用两个函数执行:query()evaluate()。虽然两者都执行查询,但区别在于它们返回的结果类型,query() 返回 DOMNodeList,而 evaluate() 则尽可能返回类型化结果。
  • 使用 XPath 可以使代码更简洁、更高效。在比较测试中,使用纯 XPath 的速度优势相当明显,XPath 版本比非 XPath 版本快约 10%。
  • PHP DOM 允许您使用自定义功能扩展标准 XPath 函数。这包括将 PHP 自身函数整合到 XPath 查询中,以及注册在 XPath 中使用的 PHP 函数。这扩展了 XPath 的功能,使其能够执行更复杂的查询。

本文将深入探讨 XPath,包括其功能和在 PHP 中的实现方式。您将发现 XPath 可以大大减少编写查询和过滤 XML 数据所需的代码量,并且通常也能提高性能。我将使用上一篇文章中相同的 DTD 和 XML 来演示 PHP DOM XPath 功能。为了快速回顾,以下是 DTD 和 XML 的样子:

<!DOCTYPE library [
  <!ELEMENT library (book*)>
  <!ELEMENT book (title, author, genre, chapter*)>
  <!ATTLIST book isbn ID #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT author (#PCDATA)>
  <!ELEMENT genre (#PCDATA)>
  <!ELEMENT chapter (chaptitle,text)>
  <!ATTLIST chapter position NMTOKEN #REQUIRED>
  <!ELEMENT chaptitle (#PCDATA)>
  <!ELEMENT text (#PCDATA)>
]>
登录后复制
登录后复制
登录后复制
登录后复制
<?xml version="1.0" encoding="utf-8"?>
<library>
  <book isbn="isbn1234">
    <title>A Book</title>
    <author>An Author</author>
    <genre>Horror</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text></text>
    </chapter>
  </book>
  <book isbn="isbn1235">
    <title>Another Book</title>
    <author>Another Author</author>
    <genre>Science Fiction</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text>Sit Dolor Amet...</text>
    </chapter>
  </book>
</library>
登录后复制
登录后复制
登录后复制
登录后复制

基本的 XPath 查询

XPath 是一种用于查询 XML 文档的语法。最简单的形式是定义您想要访问的元素的路径。使用上面的 XML 文档,以下 XPath 查询将返回所有存在的 book 元素的集合:

//library/book
登录后复制
登录后复制
登录后复制
登录后复制

就是这样。两个正斜杠表示 library 是文档的根元素,单个斜杠表示 book 是其子元素。非常简单,不是吗?但是,如果您想指定特定的书籍呢?假设您想返回任何由“An Author”撰写的书籍。该 XPath 将是:

//library/book/author[text() = "An Author"]/..
登录后复制
登录后复制
登录后复制

您可以在方括号中使用 text() 对节点的值执行比较,尾随的“/..”表示我们想要父元素(即向上移动一个节点)。XPath 查询可以使用两个函数之一执行:query()evaluate()。两者都执行查询,但区别在于它们返回的结果类型。query() 将始终返回 DOMNodeList,而 evaluate() 则尽可能返回类型化结果。例如,如果您的 XPath 查询是返回特定作者撰写的书籍数量而不是实际的书籍本身,那么 query() 将返回一个空的 DOMNodeListevaluate() 将直接返回数字,因此您可以立即使用它,而不必从节点中提取数据。

XPath 的代码和速度优势

让我们做一个快速演示,返回特定作者撰写的书籍数量。我们将首先查看一种可行的方法,但它不使用 XPath。这是为了向您展示如何在不使用 XPath 的情况下完成此操作,以及为什么 XPath 如此强大。

<!DOCTYPE library [
  <!ELEMENT library (book*)>
  <!ELEMENT book (title, author, genre, chapter*)>
  <!ATTLIST book isbn ID #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT author (#PCDATA)>
  <!ELEMENT genre (#PCDATA)>
  <!ELEMENT chapter (chaptitle,text)>
  <!ATTLIST chapter position NMTOKEN #REQUIRED>
  <!ELEMENT chaptitle (#PCDATA)>
  <!ELEMENT text (#PCDATA)>
]>
登录后复制
登录后复制
登录后复制
登录后复制

下一种方法实现了相同的结果,但使用 XPath 来选择仅由特定作者撰写的书籍:

<?xml version="1.0" encoding="utf-8"?>
<library>
  <book isbn="isbn1234">
    <title>A Book</title>
    <author>An Author</author>
    <genre>Horror</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text></text>
    </chapter>
  </book>
  <book isbn="isbn1235">
    <title>Another Book</title>
    <author>Another Author</author>
    <genre>Science Fiction</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text>Sit Dolor Amet...</text>
    </chapter>
  </book>
</library>
登录后复制
登录后复制
登录后复制
登录后复制

请注意,我们这次消除了 PHP 对作者值进行测试的需要。但是,我们还可以更进一步,使用 XPath 函数 count() 来计算此路径的出现次数。

//library/book
登录后复制
登录后复制
登录后复制
登录后复制

我们只需一行 XPath 就能检索到所需信息,无需使用 PHP 执行费力的过滤。事实上,这是一种编写此功能的更简单、更简洁的方法!请注意,在最后一个示例中使用了 evaluate()。这是因为函数 count() 返回类型化结果。使用 query() 将返回 DOMNodeList,但您会发现它是一个空列表。这不仅使您的代码更简洁,而且还具有速度优势。我发现版本 1 的平均速度比版本 2 快 30%,但版本 3 比版本 2 快约 10%(比版本 1 快约 15%)。虽然这些测量结果会根据您的服务器和查询而有所不同,但使用纯 XPath 通常会带来相当大的速度优势,同时还能使您的代码更易于阅读和维护。

XPath 函数

XPath 可以使用相当多的函数,并且有很多优秀的资源详细说明了可用的函数。如果您发现自己正在迭代 DOMNodeLists 或比较 nodeValues,您可能会发现一个 XPath 函数可以消除很多 PHP 代码。您已经看到了 count() 函数的用法。让我们使用 id() 函数来返回具有给定 ISBN 的书籍的标题。您需要使用的 XPath 表达式是:

//library/book/author[text() = "An Author"]/..
登录后复制
登录后复制
登录后复制

请注意,此处要搜索的值用引号括起来并用空格分隔;无需使用逗号分隔术语。

<?php
public function getNumberOfBooksByAuthor($author) {
    $total = 0;
    $elements = $this->domDocument->getElementsByTagName("author");
    foreach ($elements as $element) {
        if ($element->nodeValue == $author) {
            $total++;
        }
    }
    return $total; // 修正:这里应该是 $total,而不是 $number
}
?>
登录后复制
登录后复制

在 XPath 中执行复杂函数相对简单;诀窍是熟悉可用的函数。

在 XPath 中使用 PHP 函数

有时您可能会发现自己需要一些标准 XPath 函数无法提供的更强大的功能。幸运的是,PHP DOM 还允许您将 PHP 自身函数整合到 XPath 查询中。让我们考虑返回书籍标题中的单词数量。最简单的函数,我们可以这样编写方法:

<!DOCTYPE library [
  <!ELEMENT library (book*)>
  <!ELEMENT book (title, author, genre, chapter*)>
  <!ATTLIST book isbn ID #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT author (#PCDATA)>
  <!ELEMENT genre (#PCDATA)>
  <!ELEMENT chapter (chaptitle,text)>
  <!ATTLIST chapter position NMTOKEN #REQUIRED>
  <!ELEMENT chaptitle (#PCDATA)>
  <!ELEMENT text (#PCDATA)>
]>
登录后复制
登录后复制
登录后复制
登录后复制

但是,我们也可以将函数 str_word_count() 直接整合到 XPath 查询中。为此需要完成几个步骤。首先,我们必须使用 XPath 对象注册一个命名空间。XPath 查询中的 PHP 函数以“php:functionString”开头,然后是您想要使用的函数的名称,括在括号中。此外,要定义的命名空间是 http://php.net/xpath。命名空间必须设置为这个;任何其他值都会导致错误。然后,我们需要调用 registerPHPFunctions(),它告诉 PHP 每当遇到以“php:”为命名空间的函数时,都应该由 PHP 处理它。调用函数的实际语法是:

<?xml version="1.0" encoding="utf-8"?>
<library>
  <book isbn="isbn1234">
    <title>A Book</title>
    <author>An Author</author>
    <genre>Horror</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text></text>
    </chapter>
  </book>
  <book isbn="isbn1235">
    <title>Another Book</title>
    <author>Another Author</author>
    <genre>Science Fiction</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text>Sit Dolor Amet...</text>
    </chapter>
  </book>
</library>
登录后复制
登录后复制
登录后复制
登录后复制

将所有这些放在一起,得到 getNumberOfWords() 的以下重新实现:

//library/book
登录后复制
登录后复制
登录后复制
登录后复制

请注意,您不需要调用 XPath 函数 text() 来提供节点的文本。registerPHPFunctions() 方法会自动执行此操作。但是,以下同样有效:

//library/book/author[text() = "An Author"]/..
登录后复制
登录后复制
登录后复制

注册 PHP 函数不仅限于 PHP 自带的函数。您可以定义自己的函数并在 XPath 中提供这些函数。唯一的区别是,在定义函数时,您使用“php:function”而不是“php:functionString”。此外,只能提供函数本身或静态方法。不支持调用实例方法。让我们使用一个超出类范围的常规函数来演示基本功能。我们将使用的函数将仅返回“乔治·奥威尔”的书籍。对于您希望包含在查询中的每个节点,它必须返回 true

<?php
public function getNumberOfBooksByAuthor($author) {
    $total = 0;
    $elements = $this->domDocument->getElementsByTagName("author");
    foreach ($elements as $element) {
        if ($element->nodeValue == $author) {
            $total++;
        }
    }
    return $total; // 修正:这里应该是 $total,而不是 $number
}
?>
登录后复制
登录后复制

传递给函数的参数是 DOMElements 数组。函数负责迭代数组并确定要测试的节点是否应在 DOMNodeList 中返回。在此示例中,要测试的节点是 /book,我们使用 /author 来进行确定。现在我们可以创建方法 getGeorgeOrwellBooks()

<?php
public function getNumberOfBooksByAuthor($author) {
    $query = "//library/book/author[text() = '$author']/..";
    $xpath = new DOMXPath($this->domDocument);
    $result = $xpath->query($query);
    return $result->length;
}
?>
登录后复制

如果 compare() 是一个静态方法,那么您需要修改 XPath 查询,使其读取:

<?php
public function getNumberOfBooksByAuthor($author) {
    $query = "count(//library/book/author[text() = '$author']/..)";
    $xpath = new DOMXPath($this->domDocument);
    return $xpath->evaluate($query);
}
?>
登录后复制

事实上,所有这些功能都可以轻松地仅用 XPath 编写,但该示例展示了如何扩展 XPath 查询以使其更复杂。在 XPath 中无法调用对象方法。如果您发现需要访问某些对象属性或方法来完成 XPath 查询,最好的解决方案是使用 XPath 完成您能做到的部分,然后根据需要使用任何对象方法或属性处理生成的 DOMNodeList

总结

XPath 是一种在处理 XML 数据时减少代码编写量并加快代码执行速度的好方法。虽然不是官方 DOM 规范的一部分,但 PHP DOM 提供的附加功能允许您使用自定义功能扩展标准 XPath 函数。这是一个非常强大的功能,随着您对 XPath 函数的熟悉程度提高,您可能会发现自己越来越少地依赖它。

(图片来自 Fotolia)

关于使用 XPath 的 PHP DOM 的常见问题解答 (FAQ)

什么是 XPath,它如何在 PHP DOM 中使用?

XPath(XML 路径语言)是一种查询语言,用于从 XML 文档中选择节点。在 PHP DOM 中,XPath 用于遍历 XML 文档中的元素和属性。它允许您通过多种方法找到并选择 XML 文档的特定部分,例如按名称选择节点、按其属性值选择节点或按其在文档中的位置选择节点。这使得它成为在 PHP 中解析和操作 XML 数据的强大工具。

如何创建 DOMXPath 的实例?

要创建 DOMXPath 的实例,您首先需要创建一个 DOMDocument 类的实例。获得 DOMDocument 对象后,您可以通过将 DOMDocument 对象传递给 DOMXPath 构造函数来创建一个新的 DOMXPath 对象。这是一个示例:

<!DOCTYPE library [
  <!ELEMENT library (book*)>
  <!ELEMENT book (title, author, genre, chapter*)>
  <!ATTLIST book isbn ID #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT author (#PCDATA)>
  <!ELEMENT genre (#PCDATA)>
  <!ELEMENT chapter (chaptitle,text)>
  <!ATTLIST chapter position NMTOKEN #REQUIRED>
  <!ELEMENT chaptitle (#PCDATA)>
  <!ELEMENT text (#PCDATA)>
]>
登录后复制
登录后复制
登录后复制
登录后复制

如何使用 XPath 选择节点?

您可以使用 DOMXPath 对象的 query() 方法选择节点。query() 方法将 XPath 表达式作为参数,并返回一个包含与表达式匹配的所有节点的 DOMNodeList 对象。例如:

<?xml version="1.0" encoding="utf-8"?>
<library>
  <book isbn="isbn1234">
    <title>A Book</title>
    <author>An Author</author>
    <genre>Horror</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text></text>
    </chapter>
  </book>
  <book isbn="isbn1235">
    <title>Another Book</title>
    <author>Another Author</author>
    <genre>Science Fiction</genre>
    <chapter position="first">
      <chaptitle>chapter one</chaptitle>
      <text>Sit Dolor Amet...</text>
    </chapter>
  </book>
</library>
登录后复制
登录后复制
登录后复制
登录后复制

这将选择所有作为 <book> 元素子元素的 <title> 元素。

DOMXPath 中 query()evaluate() 方法的区别是什么?

query()evaluate() 方法都用于评估 XPath 表达式。区别在于它们返回的结果类型。query() 方法返回与 XPath 表达式匹配的所有节点的 DOMNodeList。另一方面,evaluate() 返回类型化结果,例如布尔值、数字或字符串,具体取决于 XPath 表达式。如果表达式结果为节点集,evaluate() 将返回 DOMNodeList。

如何在 XPath 查询中处理命名空间?

要在 XPath 查询中处理命名空间,您需要使用 registerNamespace() 方法将命名空间注册到 DOMXPath 对象。此方法有两个参数:前缀和命名空间 URI。注册命名空间后,您可以在 XPath 查询中使用前缀。例如:

//library/book
登录后复制
登录后复制
登录后复制
登录后复制

如何使用 XPath 选择属性?

您可以使用 @ 符号后跟属性名称来选择 XPath 中的属性。例如,要选择 <a></a> 元素的所有 href 属性,您可以使用以下 XPath 表达式://a/@href

如何在 PHP DOM 中使用 XPath 函数?

XPath 提供了许多可以在 XPath 表达式中使用的函数。这些函数可用于操作字符串、数字、节点集等等。要在 PHP DOM 中使用 XPath 函数,只需在 XPath 表达式中包含该函数即可。例如,要选择所有具有价格元素且值大于 30 的 <book> 元素,您可以使用 number() 函数,如下所示://book[number(price) > 30]

我可以在 PHP DOM 中将 XPath 与 HTML 文档一起使用吗?

是的,您可以在 PHP DOM 中将 XPath 与 HTML 文档一起使用。但是,由于 HTML 不总是格式良好的 XML,因此在尝试将 XPath 与 HTML 一起使用时可能会遇到问题。为了避免这些问题,您可以使用 DOMDocument 类的 loadHTML() 方法加载 HTML 文档。此方法将解析 HTML 并纠正任何格式错误,允许您将 XPath 与生成的 DOMDocument 对象一起使用。

如何在 PHP DOM 中使用 XPath 时处理错误?

在 PHP DOM 中使用 XPath 时,可能会由于多种原因发生错误,例如 XPath 表达式格式错误或无法加载 XML 文档。为了处理这些错误,您可以使用 libxml_use_internal_errors() 函数启用用户错误处理。此函数将导致 libxml 错误存储在内部,允许您在代码中处理它们。然后,您可以使用 libxml_get_errors() 函数检索错误并根据需要处理它们。

我可以使用 PHP DOM 中的 XPath 修改 XML 文档吗?

虽然 XPath 本身不提供修改 XML 文档的方法,但您可以将 XPath 与 DOM API 结合使用来修改 XML 文档。您可以使用 XPath 选择要修改的节点,然后使用 DOM API 提供的方法进行修改。例如,您可以使用 DOMNode 类的 removeChild() 方法删除节点,或使用 DOMElement 类的 setAttribute() 方法更改属性的值。

以上是PHP DOM:使用XPATH的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1666
14
CakePHP 教程
1425
52
Laravel 教程
1327
25
PHP教程
1273
29
C# 教程
1253
24
说明PHP中的安全密码散列(例如,password_hash,password_verify)。为什么不使用MD5或SHA1? 说明PHP中的安全密码散列(例如,password_hash,password_verify)。为什么不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,应使用password_hash和password_verify函数实现安全的密码哈希处理,不应使用MD5或SHA1。1)password_hash生成包含盐值的哈希,增强安全性。2)password_verify验证密码,通过比较哈希值确保安全。3)MD5和SHA1易受攻击且缺乏盐值,不适合现代密码安全。

PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP:网络开发的关键语言 PHP:网络开发的关键语言 Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP行动:现实世界中的示例和应用程序 PHP行动:现实世界中的示例和应用程序 Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP类型提示如何起作用,包括标量类型,返回类型,联合类型和无效类型? PHP类型提示如何起作用,包括标量类型,返回类型,联合类型和无效类型? Apr 17, 2025 am 12:25 AM

PHP类型提示提升代码质量和可读性。1)标量类型提示:自PHP7.0起,允许在函数参数中指定基本数据类型,如int、float等。2)返回类型提示:确保函数返回值类型的一致性。3)联合类型提示:自PHP8.0起,允许在函数参数或返回值中指定多个类型。4)可空类型提示:允许包含null值,处理可能返回空值的函数。

PHP的持久相关性:它还活着吗? PHP的持久相关性:它还活着吗? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

PHP和Python:代码示例和比较 PHP和Python:代码示例和比较 Apr 15, 2025 am 12:07 AM

PHP和Python各有优劣,选择取决于项目需求和个人偏好。1.PHP适合快速开发和维护大型Web应用。2.Python在数据科学和机器学习领域占据主导地位。

PHP与其他语言:比较 PHP与其他语言:比较 Apr 13, 2025 am 12:19 AM

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

See all articles