[User:root Time:00:49:36 Path:/home/liangdong/php]$ php xpath.php 
object(SimpleXMLElement)#5 (1) {
  ["@attributes"]=>
  array(1) {
    ["resource"]=>
    string(5) "small"
  }
}
object(SimpleXMLElement)#6 (1) {
  ["@attributes"]=>
  array(1) {
    ["resource"]=>
    string(5) "white"
  }
}
object(SimpleXMLElement)#5 (1) {
  ["@attributes"]=>
  array(1) {
    ["resource"]=>
    string(1) "5"
  }
}
[User:root Time:00:49:37 Path:/home/liangdong/php]$ cat xpath.php 
<?php
$str = <<<EOF
<?xml version="1.0" encoding="utf8" ?>
<pets>
<pet id="01">
  <type resource="big"/>
  <color resource="black"/>
  <age resource="2"/>
</pet>
<pet id="02">
  <type resource="small"/>
  <color resource="white"/>
  <age resource="5"/>
</pet> 
</pets>
EOF;$xml = simplexml_load_string($str, "SimpleXMLElement", LIBXML_NOBLANKS);
$res = $xml->xpath("/pets/pet[type[@resource='small'] and color[@resource='white'] and age[@resource='5']]");
foreach ($res as $node) { 
        $children = $node->children();
        foreach ($children as $child) {
                var_dump($child);
                //echo $child->getName() . ":" . $child['resource'] . PHP_EOL;
        }
}
?>看倒数第三行那个$child['resource'],为什么对象可以这样访问呢。object(SimpleXMLElement)#5 (1) {
  ["@attributes"]=>
  array(1) {
    ["resource"]=>
    string(5) "small"
  }
}你看,这就很神奇了,怎么实现的,搞的和JS一样,试了各种方法也没弄出来。

解决方案 »

  1.   

    array(1)  这里不是有array 保留字吗? 所有属性/值 组成关联数组。操作方法是跟js类似。
      

  2.   


    怎么自己构造一个SimpleXMLElement这样的类对象, 可以用$object['属性名']访问,这里这个:["@attributes"]=> 是啥玩意,$child->{"@attributes"}['resource'] 这样我能理解,但它直接$child['resource'],怎么整的,我没记得php可以[]访问属性啊。
      

  3.   

    @attributes 代表元素的属性。
    可通过 SimpleXMLElement::__construct  来构造一个 SimpleXMLElement  对象。
    参考:http://www.php.net/manual/en/simplexmlelement.construct.php
      

  4.   

     foreach ($children as $child) {
                    echo "<pre>";
    print_r($child);
                    echo "</pre>";
                    //echo $child->getName() . ":" . $child['resource'] . PHP_EOL;
            }
    数组对象,双重功能啊,没明白
      

  5.   

    你是问对象如何实现迭代器?
    如果是,就看
    http://php.net/manual/en/language.oop5.iterations.php
      

  6.   


    并不是问迭代器,迭代器圣经里学过了。是问SimpleXMLElement是怎么实现[]下标访问的,它是一个object啊。
      

  7.   

    由 object(SimpleXMLElement)#5 (1) {
      ["@attributes"]=>
      array(1) {
      ["resource"]=>
      string(5) "small"
      }
    } 可知 @attributes 的成员是一个数组,当然就可以用关联键 resource 访问了
    另外,根据 domxml 的约定,他也可以按对象方式访问 ->resource
    无论使用哪种方式方式访问,实际上都是 __tostring 方法的结果
      

  8.   


    object有个成员变量叫做@attributes,这个变量是一个array(), array()里有一个resource。为什么不是这样理解的,我晕了。
      

  9.   

    像你 #2 的 $child->{"@attributes"}['resource'] 写法,我不知道是否可行
    XML 在最初诞生时是没有属性一说的,后来有了属性(也是要么全是属性,要么全是节点)
    想现在的这种混合样式,已经是人们决定放弃XML的主要理由之一了在 DOMXML 中,属性始终是需要通过 attributes 节点获取的。php 也不例外(通过 attributes 方法)
    其他变通的用法只能造成混乱,不但你看不懂,其他人也看不懂
      

  10.   

    首先一个对象要想能被foreach遍历,则必须实现迭代器。
    所以看手册写着
    SimpleXMLElement implements Traversable 
    而Traversable的介绍是
    Internal (built-in) classes that implement this interface can be used in a foreach construct and do not need to implement IteratorAggregate or Iterator
    为什么不直接用Iterator呢,所以肯定是有一些额外的特殊特征,所以我觉得你这个问题可能必须得去看php的C源码了,因为Traversable是内置的,无法通过php代码实现。
      

  11.   

    熟悉spl 开发更轻松。
    SPL库中的迭代器接口
    SPL提供了6个迭代器接口,如下表
    Traversable 遍历接口(检测一个类是否可以使用 foreach 进行遍历的接口)
    Iterator 迭代器接口(可在内部迭代自己的外部迭代器或类的接口)
    IteratorAggregate 聚合式迭代器接口(创建外部迭代器的接口)
    OuterIterator 迭代器嵌套接口(将一个或多个迭代器包裹在另一个迭代器中)
    RecursiveIterator 递归迭代访问接口(提供递归访问功能)
    SeekableIterator 可索引迭代访问接口(实现查找功能)