1

如何在 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>

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

4

6 回答 6

5

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

它在这里查找最后一个 inner <obj>,并在其中查找<int>名称为 的"energy_in_kwh"

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


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

于 2008-11-17T10:17:53.273 回答
4

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

于 2008-11-17T10:24:09.423 回答
1

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

于 2008-11-17T09:02:14.923 回答
0

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

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

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

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

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

如果您需要更复杂的查询并且速度不是问题:那么使用最容易实现并提供所需功能的任何东西(XPath 适用于复杂的树导航,数组索引适用于列表类型数据结构中的快速随机访问; XML 可用于两者。)

于 2008-11-17T08:56:13.843 回答
0

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

<?php
$s = simplexml_load_file('in.xml');
$s->registerXPathNamespace('obix', 'http://obix.org/ns/schema/1.0');
$items = $s->xpath('//obix:list');
?>
于 2008-11-17T09:30:35.990 回答
0

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

    <?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>,否则它会返回不同的结果。

于 2014-11-26T16:38:28.473 回答