如何在php中使用DOMXPath在特定上下文中查找元素?

时间:2017-01-07 15:40:21

标签: php xml xpath domdocument domxpath

我正在尝试使用有关某些用户的信息解析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 );

2 个答案:

答案 0 :(得分:1)

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

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

请参阅demo

中的结果

答案 1 :(得分:1)

位置路径起点处的斜杠(/)使其相对于文档节点。上下文节点将被忽略。如果后跟另一个斜杠,则使用后代轴。 //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"