【问题标题】:PHP SimpleXML. How to get the last item?PHP SimpleXML。如何获得最后一项?
【发布时间】:2008-11-17 08:47:19
【问题描述】:

如何在 simplexml 对象中获取最后一项(或任何特定项)?假设你不知道会有多少个节点。

例如

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/xsl.xml"?>
<obj 
  href="http://xml.foo.com/" 
  display="com.foo.bar" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://obix.org/ns/schema/1.0" 
>
 <list name="data" of="HistoryRecord">
  <obj>
   <abstime name="timestamp" val="1876-11-10T00:00:00-08:00"></abstime>
   <int name="energy_in_kwh" val="1234"></int>
   <int name="energy_out_kwh" val="123456"></int>
  </obj>
  <obj>
   <abstime name="timestamp" val="1876-11-10T00:15:00-08:00"></abstime>
   <int name="energy_in_kwh" val="1335"></int>
   <int name="energy_out_kwh" val="443321"></int>
  </obj>
 </list>
 <int name="count" val="2"></int>
</obj>

我想获取最后一个 &lt;obj&gt;&lt;/obj&gt; 块(甚至只是其中的一部分)。

【问题讨论】:

    标签: php xml simplexml


    【解决方案1】:

    使用 XPath 的 last() 函数,它解决了这个问题:

    <?php 
    $xml = simplexml_load_file('HistoryRecord.xml'); 
    $xml->registerXPathNamespace('o', 'http://obix.org/ns/schema/1.0');
    
    $xpath = "/o:obj/o:list/o:obj[last()]/o:int[@name = 'energy_in_kwh']";
    $last_kwh = $xml->xpath($xpath); 
    ?> 
    

    在这里查找最后一个内部&lt;obj&gt;,并在其中查找名称为"energy_in_kwh"&lt;int&gt;

    注意命名空间注册。 (您的所有元素都是 "http://obix.org/ns/schema/1.0" 命名空间的一部分,XPath 查询必须反映这一点。


    编辑:注意[last()] 等同于[position() = last()]

    【讨论】:

    • 你测试过这段代码吗?我刚刚运行它,它没有工作。 $last_kwh 返回 false;
    • 可能是因为缺少命名空间注册。我没有注意到它,因为它在问题中不在屏幕上。
    【解决方案2】:

    有一个 XPath 表达式可以完全满足您的需求:

    $xml='<?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="/xsl.xml"?>
    <obj href="http://xml.foo.com/" display="com.foo.bar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://obix.org/ns/schema/1.0" >
     <list name="data" of="HistoryRecord">
      <obj>
       <abstime name="timestamp" val="1876-11-10T00:00:00-08:00"></abstime>
       <int name="energy_in_kwh" val="1234"></int>
       <int name="energy_out_kwh" val="123456"></int>
      </obj>
      <obj>
       <abstime name="timestamp" val="1876-11-10T00:15:00-08:00"></abstime>
       <int name="energy_in_kwh" val="1335"></int>
       <int name="energy_out_kwh" val="443321"></int>
      </obj>
     </list>
     <int name="count" val="2"></int>
    </obj>';
    $x=simplexml_load_string($xml);
    $x->registerXPathNamespace('obix', 'http://obix.org/ns/schema/1.0');
    $objects=$x->xpath('/obix:obj/obix:list/obix:obj[last()]');
    print_r($objects);
    

    例如,/bookstore/book[last()] 将选择作为 bookstore 元素的子元素的最后一个 book 元素。

    【讨论】:

    • 忘记了 XPath 表达式中的命名空间前缀...抱歉!
    【解决方案3】:

    对于程序员来说,访问 XML 中节点的最快方法是 XPath。看看xpath methodsxpath itself

    【讨论】:

      【解决方案4】:

      你可以从这个开始..你可以把它挖出来..我不喜欢他们在 2 个级别使用相同的标签名称..我尽量避免重复的标签名称。

      <?php
      $s = simplexml_load_file('in.xml');
      $s->registerXPathNamespace('obix', 'http://obix.org/ns/schema/1.0');
      $items = $s->xpath('//obix:list');
      ?>
      

      【讨论】:

        【解决方案5】:

        我认为 SimpleXML 无论如何都会加载整个 XML,并且(如果我没记错的话)您可以像使用数组一样使用 SimpleXML 节点,因此您可以只使用数组函数来获取最后一个节点。自从我使用 PHP 以来已经有一段时间了,但是您应该能够获取长度,然后以 length-1 获取项目...

        编辑: 当然,您也可以使用 XPath,我想我也应该提到这一点,但我不确定 last() 是否在 SimpleXML XPath 实现中工作。

        我不确定哪个是最快的,使用数组索引或 XPath,我猜数组索引更快,但你应该在循环中尝试几千次,以获得循环前后的时间来检查。

        但在 CS 中总是如此:你选择什么取决于很多事情。

        时间紧迫还是经常使用:然后找到最快的解决方案。

        如果您需要更复杂的查询并且速度不是问题:然后使用最容易实现并提供所需功能的任何方法(XPath 适合复杂的树导航,数组索引适合快速随机访问列表-type 数据结构;两者都可以使用 XML。)

        【讨论】:

          【解决方案6】:

          如前所述,您可以使用数组表示法和函数。

              <?php 
              $xml = simplexml_load_file('HistoryRecord.xml'); 
              $lastObj = $xml->list->obj[$xml->list->obj->count()-1];
          

              $lastObj = $xml->list->obj[count($xml->list->obj)-1];
          

          你也可以使用end() 来获取最后一个元素,但前提是你总是有多个,否则它会返回不同的结果。

          【讨论】:

            猜你喜欢
            • 2013-01-16
            • 1970-01-01
            • 2014-07-02
            • 2010-09-07
            • 2010-10-20
            • 2011-01-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多