代码之家  ›  专栏  ›  技术社区  ›  rg88

PHP SimpleXML。如何获得最后一项?

  •  1
  • rg88  · 技术社区  · 16 年前

    前任。

    <?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>
    

    我想抓住最后一个 <obj></obj> 块(甚至只是它的一部分)。

    6 回复  |  直到 16 年前
        1
  •  5
  •   Tomalak    13 年前

    使用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); 
    ?> 
    

    <obj> ,并于此 <int> 名为 "energy_in_kwh" .

    "http://obix.org/ns/schema/1.0" 而XPath查询必须反映这一点。


    编辑:注意 [last()] 相当于 [position() = last()] .

        2
  •  4
  •   Stefan Gehrig    16 年前

    有一个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元素。

        4
  •  0
  •   DreamWerx    16 年前

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

    <?php
    $s = simplexml_load_file('in.xml');
    $s->registerXPathNamespace('obix', 'http://obix.org/ns/schema/1.0');
    $items = $s->xpath('//obix:list');
    ?>
    
        5
  •  0
  •   Stein G. Strindhaug    16 年前

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

    我不确定wich是否最快,使用数组索引或XPath,我猜数组索引更快,但您应该在循环中尝试这两种方法数千次,以获得循环前后的检查时间。

    但在CS中,你的选择取决于很多事情。

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

        6
  •  0
  •   Victor    10 年前

    正如前面提到的,您可以使用数组表示法和函数。

        <?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() 获取最后一个元素,但前提是始终有多个<obj>,否则将返回不同的结果。