【问题标题】:How to find element in specific context using DOMXPath in php?如何在 php 中使用 DOMXPath 在特定上下文中查找元素?
【发布时间】:2017-01-07 15:40:20
【问题描述】:

我正在尝试解析包含某些用户信息的 xml 文件。像这样的

users.xml

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>
        <name>Alexander</name>
        <email>alexander@test.com</email>
    </user>
    <user>
        <name>Tyler</name>
        <email>tyler@test.com</email>
    </user>
</users>

我正在使用DOMXpath 提取此 xml 中的所有用户以及所有这些字段。 在 xml 文件中,我有 15 个用户,当我在此代码中搜索有关一个用户的所有字段时

$username = $xpath->query ( '//email', $users->item(0) );

我得到了 15 个长度,而不是 1。我的意思是 query 正在搜索所有 xml,而不是寻找实际用户。 我做错了什么?

xml_query.php

$xml = new DOMDocument();
$xml->loadXML( $xml_content );
$xpath = new DOMXPath($xml);

$users = $xpath->query( '//user' );
var_dump( $users->item(0) );
$username = $xpath->query ( '//email', $users->item(0) );

var_dump( $username );

【问题讨论】:

  • DOMXPath 参数应该是 DOMDocument 的类型而不是 xml 文件。
  • 我在代码中错过了两条通道,DOMXPath 在构造函数 @Mohammad 中有 DOMDocument
  • //email中删除//

标签: php xml xpath domdocument domxpath


【解决方案1】:

因为//email 选择文档中的所有元素,但您需要选择当前上下文中的元素。从查询表达式中删除 //

$username = $xpath->query ( 'email', $users->item(0) );

查看demo中的结果

【讨论】:

  • 有了email 现在我得到length 0 。
  • ('./email', $context) 在许多情况下会更具体(因此防错)。
【解决方案2】:

位置路径开头的斜杠 (/) 使其相对于文档节点。上下文节点将被忽略。如果后面跟着另一个斜线,则使用后代轴。 //email/descendant::email 的缩写。默认轴为child

$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>
        <name>Alexander</name>
        <email>alexander@test.com</email>
    </user>
    <user>
        <name>Tyler</name>
        <email>tyler@test.com</email>
    </user>
</users>
XML;

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate('//user') as $user) {
  var_dump($xpath->evaluate('string(email)', $user));
}

输出:

string(18) "alexander@test.com"
string(14) "tyler@test.com"

DOMXpath::evaluate() 可以根据表达式返回节点列表或标量。它允许您直接在 Xpath 表达式中将节点转换为字符串。

Xpath 表达式可以包含条件,因此要按位置输出电子邮件,您可以执行以下操作:

foreach ($xpath->evaluate('//user[2]') as $user) {
  var_dump($xpath->evaluate('string(email)', $user));
}

输出:

string(14) "tyler@test.com"

【讨论】:

    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 2021-10-15
    • 2017-03-17
    • 2014-07-18
    相关资源
    最近更新 更多