SimpleXMLElement和xpath

时间:2014-10-21 16:21:19

标签: php xpath simplexml

我有一个类似于:

的XML文档
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:zapi="http://zotero.org/ns/api">
  <link rel="up" type="application/atom+xml" href="some link"/>
</entry>

我想要link元素的“up”(rel属性),所以我这样做:

$xml = new SimpleXMLElement($body);
$php_up = $xml->xpath("//link[@rel='up']");
var_dump($php_up); exit;

只是给了我array(0) { }

我做错了什么?

3 个答案:

答案 0 :(得分:1)

您不需要XPATH来获取REL属性。这应该很简单:

$php_up = $xml->link->attributes()->rel;

更新:获取多个链接元素的属性:

XML:

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:zapi="http://zotero.org/ns/api">
  <link rel="up" type="application/atom+xml" href="some link"/>
  <link rel="down" type="application/atom+xml" href="some link"/>
</entry>

PHP:

$xml = new SimpleXMLElement($body);

foreach ($xml->link as $link) {
    $rels[] = (string)$link->attributes()->rel;
}
var_dump($rels); exit;

答案 1 :(得分:1)

XML第二行中的声明提供了两个XML命名空间:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:zapi="http://zotero.org/ns/api">

第一个xmlns属性,没有以冒号分隔的后缀,将entry元素的“默认”命名空间设置为http://www.w3.org/2005/Atom,而没有前缀的后代节点位于命名空间默认。为了能够使用XPath使用“默认”命名空间访问这些元素,您需要使用registerXPathNamespace设置命名空间,然后执行查询,为您要查找的元素添加前缀(link)使用命名空间:

$xml->registerXPathNamespace('d', 'http://www.w3.org/2005/Atom');
$php_up = $xml->xpath("//d:link[@rel='up']");
var_dump($php_up);

输出:

array(1) {
  [0] =>
  class SimpleXMLElement#2 (1) {
    public $@attributes =>
    array(3) {
      'rel' =>
      string(2) "up"
      'type' =>
      string(20) "application/atom+xml"
      'href' =>
      string(9) "some link"
    }
  }
}

答案 2 :(得分:0)

它不会很明显,但您需要在str_replace上使用xmlns:)

$body= str_replace('xmlns=', 'ns=', $body);

致电$xml = new SimpleXMLElement($body);

之前

Here's your eval.in