php 使用xpath_在PHP中使用XPath

php 使用xpath

在本文中,了解以下概念:

  • 用于XPath
  • 编写基本的XPath表达式
  • 使用PHP XML库的XPath功能
  • 使用XPath和PHP转换数据格式

本文提供了几个可以结合使用XPath和PHP的工作示例,并假设您具有Prerequisites中描述的先决条件

先决条件

为了从本文中获得最大收益,您应该具有XML和PHP5知识以及配置和安装PHP扩展。 此外,您还需要访问并了解带有支持PHP5的Web服务器的基于UNIX®或Microsoft®Windows®操作系统的知识,并可以在本文上练习本文中的代码示例。

了解对XPath的需求

随着Web向语义Web的原始愿景发展,应用程序之间的交互性也越来越强。 诸如SOAP,REST,RSS,RDF之类的技术以及其他技术是未来Web的强大推动者。 在大多数情况下,XML是用来描述所涉及数据的选定消息格式。 在某种程度上,您可以使用JSON,但您可能会将XML视为主要的数据交换方法。

或者,您可能会遇到将XML数据转换为XHTML,以为移动用户和各种Web浏览器提供有吸引力的,交互式的和可用的界面的任务。

将数据作为XML文档存储到文件系统或XML兼容数据库也是一种流行的方式来存档数据,以供以后检索以执行报告,用户界面显示或应用程序集成等任务。

使用XML数据时,您需要解析数据以获取最小公分母-所需数据(或原子节点值,通常称为原子节点值)。 XSLT是W3C标准,它执行XML到另一种格式的转换,例如HTML,PDF,甚至是另一种使用不同模式的XML文档。 XQuery,XForms和XPointer都非常依赖XPath的使用。

XPath背景

以最简单的形式,XPath是一种用于在内存中导航XML树的语言。 最初,XPath被设计为XSLT和XPointer的语言。 XPath 1.0在1999年成为W3C标准。较新的XPath 2.0在2007年获得规范状态。

随着其他XML规范的出现,XPath的使用也出现了。 如今,XPath已成为在XML模式,ISO Schematron,XQuery和XForms中导航XML的首选语言。 具有讽刺意味的是,但有充分的理由,XPath不是基于XML语法的。 它使用自己的语法来避免与URI和其他XML相关语法的冲突。

在PHP中使用XPath时,请记住不要单独使用XPath。 您可以使用它作为在其他XML规范之一中工作时在内存中浏览XML的工具。

出于本文的目的,我在讨论和示例中使用了更广泛使用的XPath 1.0规范。 XPath 2.0向后兼容XPath 1.0,但是PHP今天对XPath 2.0的支持有限。

XPath规范提供了其标准用法和术语的详细说明。 如果您期望将XPath与PHP一起复杂使用,则此规范是可靠的参考点。 否则,XPath规范可以归纳为四个主要的关注领域,如表1所示

表1. XPath规范的四个主要领域
描述 例子
位置路径 包含位置步骤,轴,谓词和缩写语法。 父::节点,子::文本(),属性:: *,/ PRODUCTS / PRODUCT [3] / NAME
资料模型 将XML描述为树。 包含根,属性,文本,名称空间,元素,处理指令和注释的节点。 /,/ ns1:PRODUCTS / ns1:PRODUCT,@category
表达方式 可能包含变量引用,函数,布尔值,数字,字符串和谓词。 / PRODUCTS / PRODUCT / NAME [字符串长度()> 15] /../@ category
功能 XPath 1.0具有27个内置函数,这些函数分为节点集,字符串,布尔值或数字函数。 string-length(),true(),sum()

编写XPath表达式

在编写PHP代码之前,花一些时间检查XPath节点,路径和功能。 清单1中的products.xml文件提供了一些常用表达式的示例,这些表达式可基于谓词在XML路径中定位数据,定位节点的原子值并利用函数。

清单1.示例产品XML文档(products.xml)
<?xml version="1.0" encoding="UTF-8"?>
<PRODUCTS>
<PRODUCT category="software">
<SKU>soft32323</SKU>
<SUB_CATEGORY>Business Analysis</SUB_CATEGORY>
<NAME>Widget Reporting</NAME>
<PRICE>4500</PRICE>
</PRODUCT>
<PRODUCT category="software">
<SKU>soft32323</SKU>
<SUB_CATEGORY>Business Analysis</SUB_CATEGORY>
<NAME>Pro Reporting</NAME>
<PRICE>2300</PRICE>
</PRODUCT>
<PRODUCT category="storage">
<SKU>soft32323</SKU>
<SUB_CATEGORY>Tape Systems</SUB_CATEGORY>
<NAME>Tapes Abound</NAME>
<PRICE>2300</PRICE>
</PRODUCT>
<PRODUCT category="storage">
<SKU>soft32323</SKU>
<SUB_CATEGORY>Disk Systems</SUB_CATEGORY>
<NAME>Widget100 Series</NAME>
<PRICE>6500</PRICE>
</PRODUCT>
</PRODUCTS>

/PRODUCTS返回作为PRODUCTS节点的子级的所有节点,其中有四个。 注意正斜杠( / )符号。 如果您熟悉基于UNIX的操作系统,则知道斜杠代表绝对路径。 就像在UNIX文件路径中一样,当不确定当前上下文位置时,可以使用绝对路径。 对于清单1中的文档, PRODUCTS是根节点。

相对路径也可以与XPath一起使用。 在表达式中使用..时,它会指示表达式从层次结构中的当前节点开始向上处理一级(再次类似于在UNIX操作系统中使用目录)。 例如, ../PRODUCT/SKU PRODUCT SKU返回与每个PRODUCT节点关联的所有四个SKU编号的原子节点值。

选择属性节点需要在XPath中使用特殊语法。 如果要返回软件类别中列出的所有PRODUCT节点,则表达式/PRODUCTS/PRODUCT[@category='software']执行此操作。 在此表达式中, category被视为XML文档中的属性。 XPath可以选择带有符号(@)的属性。 或者,您可以使用attribute::语法选择一个属性,使得表达式为/PRODUCTS/PRODUCT[attribute::category='software'] 。 大多数人发现at符号不太冗长,更易于使用。

要为价格超过$ 2,500的产品选择所有产品名称的原子节点值(即实际文本值),可以将表达式编写为/PRODUCTS/PRODUCT[PRICE > 2500]/NAME 。 执行时,此表达式返回产品名称Widget ReportingWidget100 Series

在将XPath与PHP结合使用之前,请看一个最终表达式示例: /PRODUCTS/PRODUCT/NAME[string-length( ) > 15]/../@category 。 执行时,此表达式返回两个值: softwarestorage 。 具体来说,此表达式匹配名称长度超过15个字符的每个产品的类别值。

清单1中的XML文档是本文演示的XPath表达式的源文档。

在PHP中发现XPath支持

PHP支持XML和XPath应该不足为奇。 实际上,最流行的Web脚本语言在其核心库中提供了一些使用XPath的良好功能。

在核心PHP库中,使用XML时,您有几种选择:

  • SimpleXML
  • DOM
  • XMLWriter /阅读器

SimpleXML易于使用,并且适用于相对简单的XML相关杂务。 它确实有一些局限性。 例如,它不完全支持验证,编写和名称空间。 如果要处理大型XML数据树,请记住,SimpleXML在处理之前将完整的XML文档树加载到内存中。

如果需要执行更复杂的XPath表达式并需要完全控制文档,则可以选择DOM。 DOM是文档对象模型的缩写,它是W3C标准。 您可以通过将PHP作为扩展安装来启用DOM。 诸如DOM之类的扩展通常很容易安装和启用。 很多时候,这只是在php.ini文件中取消注释一行以启用已编译模块的情况。 与SimpleXML一样,DOM在处理之前会将完整的XML文档树加载到内存中。 正如您将在本文后面看到的那样,DOMXPath也非常令人愉快。

您还可以从PHP扩展和应用程序存储库(PEAR)存储库下载并安装XML_XPath 。 此类使用DOM,并提供了一种使用XPath进行查询以进行文档处理和提取原子节点值的方法。

如果使用Zend Framework,则可以使用Zend_Dom_Query库。 如果您的特定PHP框架没有为XML和XPath提供特殊的类或函数,则可以简单地使用PHP已经提供的功能。

没有SimpleXML或DOMXPath的帮助,XMLWriter / Reader不会直接支持XPath,因此本文将不再赘述。

无论使用哪种库或框架,了解如何创建XPath表达式都是获得全部潜能的关键。 将XPath与PHP XML相关的库一起使用时,XPath语法是相同的。 以下示例和演示结合使用DOM和SimpleXML。

在PHP中使用XPath

使用清单1中的示例products.xml文件和PHP5 SimpleXML API,您可以尝试各种XPath表达式。

当您执行清单2中的代码时,结果当然是将完整的XML文件转储为数组。 XPath表达式/PRODUCTS导致作为根节点( PRODUCTS )的每个子节点的匹配。

清单2.使用SimpleXML显示数组中的所有节点
<?php
$xml = simplexml_load_file("products.xml");
$products = $xml->xpath("/PRODUCTS");
print_r($products);
 ?>
------------------------------------------------------------
OUTPUT:

Array ( [0] => SimpleXMLElement Object ( [PRODUCT] => 
Array ( [0] => SimpleXMLElement Object
( [@attributes] => Array ( [category] => software ) [SKU] =>
soft1234 [SUB_CATEGORY] => 
Business Analysis [NAME] => Widget Reporting [PRICE] => 4500 ) [1] => 
SimpleXMLElement Object 
( [@attributes] => Array ( [category] => software ) [SKU] => soft5678
[SUB_CATEGORY] =>
Business Analysis [NAME] => Pro Reporting [PRICE] => 2300 ) [2] => 
SimpleXMLElement Object
( [@attributes] => Array ( [category] => storage ) [SKU] => 
stor01010 [SUB_CATEGORY] => Tape Systems [NAME] => 
Tapes Abound [PRICE] => 1900 ) 
[3] => SimpleXMLElement Object ( [@attributes] => 
Array ( [category] => storage ) [SKU] => 
stor23232 [SUB_CATEGORY] => Disk Systems [NAME] => 
Widget100 Series [PRICE] => 6500 ) ) ) )

当执行清单3中的代码时,结果是XML树的每个NAME节点的值的数组输出。 请注意,表达式/PRODUCTS/PRODUCT/NAME如何在XML树中找到它匹配的每个节点的,而不是仅第一个或最后一个。

清单3.使用SimpleXML在数组中显示所有产品名称
<?php
$xml = simplexml_load_file("products.xml");
$products = $xml->xpath("/PRODUCTS/PRODUCT/NAME");
print_r($products);
 ?>
------------------------------------------------------------
OUTPUT:

Array ( [0] => SimpleXMLElement Object ( [0] => Widget Reporting ) 
[1] => SimpleXMLElement Object ( [0] => Pro Reporting ) [2] => 
SimpleXMLElement Object ( [0] => Tapes Abound ) [3] => 
SimpleXMLElement Object ( [0] => Widget100 Series ) )

如果您需要根据某些条件来确定一个或多个特定节点的值,请遵循清单45中的示例。

定位原子节点值是从XML文档中提取所需的值。 当您执行清单4中的代码时,结果是一个节点的原子值。

清单4.使用SimpleXML显示特定SKU的产品名称
<?php
$xml = simplexml_load_file("products.xml");
$products = $xml->xpath("/PRODUCTS/PRODUCT[SKU='soft5678']/NAME");
print_r($products);
 ?>
------------------------------------------------------------
OUTPUT:

Array ( [0] => SimpleXMLElement Object ( [0] => Pro Reporting ) )

XPath表达式/PRODUCTS/PRODUCT[SKU='soft5678']/NAME指定与该表达式匹配的所有节点。 在这种情况下,只有一种产品的SKU编号匹配。 如果需要定位节点的值,因为它与它在XML树中的位置有关 ,则可以使用position()函数。

您可以在XPath中使用条件表达式来进一步查明特定节点的位置。 清单5显示了一个使用带有条件表达式的SimpleXML和XPath的示例。

清单5.使用SimpleXML根据条件查找产品
<?php
$xml = simplexml_load_file("products.xml");
$products = $xml->xpath("/PRODUCTS/PRODUCT[@category='software' and PRICE > 2500]"); 
print_r($products);
 ?>
------------------------------------------------------------
OUTPUT:

Array ( [0] => SimpleXMLElement Object ( [@attributes] => 
Array ( [category] => software ) 
[SKU] => soft1234 [SUB_CATEGORY] => Business Analysis [NAME] =>
 Widget Reporting [PRICE] => 4500 ) )

您可能已经注意到,清单234 ,和5有相同PHP代码,唯一的区别是XPath表达式。 当您使用SimpleXML掌握这些步骤时,您将拥有XPath语言的全部功能。 使用SimpleXML时,PHP代码采取的步骤总结如下:

  1. 将XML文件加载到内存中。
  2. 使用Object->xpath class.编写并执行XPath表达式Object->xpath class.
  3. 使用您PHP技能来操作匹配的节点和值。

每个清单中的输出结果是print_r($products); 声明。 它转储值以显示为数组。 实际上,您很可能会得到结果并使用PHP对它执行一些操作。

清单6使用DOM和DOMXPath来处理XML和XPath。

清单6.使用DOMXPath显示特定SKU的产品名称
<?php

$doc = new DOMDocument;
$doc->load('products.xml');
$xpath = new DOMXPath($doc);
$products = $xpath->query("/PRODUCTS/PRODUCT[SKU='soft5678']/NAME");
 
foreach ($products as $product)
{
   print($product->nodeValue);
}
 ?>
------------------------------------------------------------
OUTPUT:

Pro Reporting

用于DOM和DOMXPathPHP代码序列并不比SimpleXML步骤复杂得多。 清单6中的步骤按以下顺序总结:

  1. 将XML文件从DOM对象加载到内存中。
  2. 从加载的文档中创建一个XPath对象。
  3. 查询XML树并返回一个product对象。

同样,当您对使用DOMPHP代码片段感到满意时,可以使用XPath来完成繁琐的工作。

使用XPath进行转换

实际上,您可以在不使用XSLT的情况下将XML转换为XHTML。 您可以仅使用SimpleXML或DOM扩展前面的示例并变得更有创意,并创建XHTML文件进行显示。 您可能会对这种方法更满意。 但是,考虑到XPath大量用于XSLT转换,而PHP确实支持XSLT,则适合进行演示。 此外,使用XSLT可以节省大量时间和挫败感!

在将XML数据转换为其他格式(例如使用XSLTHTML)时,必须对XPath有扎实的了解。

RSS和Atom提要基于XML,因此XPath是横切提要和选择所需数据的理想工具。 假设本文具有针对各种PHP和XPath技术的自己的Atom提要,则可以使用一个PHP XML库从提要中提取条目,并根据需要在网站上显示它们。

清单7中的文件一样简单的XSLT文件在很大程度上取决于XPath。

清单7.一个简单的XSLT文件,它将提要转换为HTML(article_feed.xsl)
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
                xmlns:atom="http://www.w3.org/2005/Atom" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:dc="http://purl.org/dc/elements/1.1/">

  <xsl:template match="/">

    <html>
      <head><title><xsl:value-of select="//atom:title"/></title></head>
      <table>
        <tr><td><xsl:value-of select="//atom:title"/></td></tr>
        <tr><td><i>"<xsl:value-of select="//atom:subtitle" />",</i></td></tr>
        <tr><td>by <xsl:value-of select="//atom:author"/></td></tr>
        <xsl:for-each select="//atom:feed/entry">
          <table border="1" >
            <tr>
              <td>Title</td><td><xsl:value-of select="//atom:title"/></td>
            </tr>
            <tr>
              <td>Summary</td><td><xsl:value-of select="//atom:summary"/></td>
            </tr>
            <tr>
            </tr>
          </table><br/>
        </xsl:for-each>
      </table>
    </html>
  </xsl:template>
</xsl:stylesheet>

两个正斜杠( // )指示XPath匹配从根节点开始的第一个命名节点。 标题,字幕和作者各只有一个节点,这是一种无需输入绝对路径即可表达位置路径的快捷方式。 因为for-each循环在//feed/entry节点的上下文中起作用,所以使用标题和摘要的相对路径。

现在,使用清单7中的XSLT文件,可以编写适当PHP代码来执行转换,如清单8所示

清单8.使用DOM进行XLST转换
<?php
$doc = new DOMDocument();
$xmlStream = <<<MyFeed
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title>Using XPath with PHP</title>
<author><name>Tracy Bost</name></author>
<subtitle type="html">
Let XPath do the hard work for you when working with XML</subtitle>
<link rel="self" type="text/html"
hreflang="en" href="http://www.ibm.com/developerworks/"/>
<updated>15 Aug 2011 22:51:48 +0000</updated>
<entry> 
<title>SimpleXML & XPath </title> 
<summary>If you are using SimpleXML to parse XML or
 RSS feeds, XPath is great to use!</summary> 
<link rel="self" type="text/html" hreflang="en" href=""/> 
<published>21 Apr 2011 04:00:00 +0000</published> 
<updated>21 Apr 2011 04:00:00 +0000</updated> 
</entry> 
<entry> 
<title>DOMXPath</title> 
<summary>If you are using DOM for traversal XML documents, 
give DOMXPath a try! </summary> 
<link rel="self" type="text/html" hreflang="en" href=""/> 
<id>tag:developerWorks.dw,19 Apr 2011 04:00:00 +0000</id> 
<published>12 Aug 2011 04:00:00 +0000</published> 
<updated>12 Aug 2011 04:00:00 +0000</updated> 
</entry> 
<entry> 
<title>XMLReader with XPath</title> 
<summary>For complex XML document reading and writing, 
using XPath with XReader can ease your burden!</summary> 
<link rel="self" type="text/html" hreflang="en" href=""/> 
<id>tag:developerWorks.dw,19 Apr 2011 04:00:00 +0000</id> 
<published>08 Aug 2011 04:00:00 +0000</published> 
<updated>08 Aug 2011 04:00:00 +0000</updated> 
</entry> 
</feed> 
MyFeed;

  
$doc->loadXML($xmlStream);
$xpath = new DOMXpath($doc);
$xslt = new XSLTProcessor();
$xsl = new DOMDocument();
$xsl->load( 'xsl/article_feed.xsl', LIBXML_NOCDATA);
$xslt->importStylesheet( $XSL );
print $xslt->transformToXML( $doc );
?>

------------------------------------------------------------
OUTPUT: 

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Using XPath with PHP</title></head><body><table><tr>
<td>Using XPath with PHP</td></tr><tr>
<td><i>"Let XPath do the hard work for you when working with XML",</i></td>
</tr><tr><td>by Tracy Bost
</td></tr><table border="1"><tr><td>Title</td>
<td>SimpleXML & XPath </td></tr>
<tr><td>Summary</td>
<td>If you are using SimpleXML to parse XML or RSS feeds,
 XPath is great to use!</td>
</tr><tr/></table>
<br/>
<table border="1">
<tr><td>Title</td>
<td>DOMXPath</td>
</tr>
<tr><td>Summary</td>
<td>If you are using DOM for traversal XML documents, 
give DOMXPath a try! </td>
</tr><tr/></table><br/>
<table border="1">
<tr><td>Title</td><td>XMLReader with XPath</td>
</tr>
<tr><td>Summary</td>
<td>For complex XML document reading and writing, 
using XPath with XReader can ease your burden!</td>
</tr><tr/></table><br/>
</table>
</body>
</html>

请注意, 清单8没有$xpath->query()语句,如清单6所示 。 所有XPath表达式都位于XSL文件中。 只需使用DOM导入样式表,然后让它执行转换即可!

摘要

在本文中,向您介绍了XPath,以及在使用XML时如何在PHP5环境中使用它。 像PHP中提供的许多其他库一样,XML库使您作为开发人员可以专注于功能需求,而不是类和对象的低级连接。 XPath可以帮助消除在XML中定位和解析数据的繁琐任务。 根据您的需求,您可以选择使用SimpleXML,DOM或诸如Zend Framework之类的框架的XML库。 幸运的是,它们都以标准方式与W3C XPath一起使用。 因此,当您加载下一个XML文件或数据流时,不必担心导航到需要处理的确切值。


翻译自: https://www.ibm.com/developerworks/opensource/library/x-xpathphp/index.html

php 使用xpath

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值