如何在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>
块(或者只是其中的一部分)。
答案 0 :(得分: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);
?>
此处查找最后一个内部<obj>
,其中<int>
的名称为"energy_in_kwh"
。
注意命名空间注册。 (所有元素都是"http://obix.org/ns/schema/1.0"
命名空间的一部分,XPath查询必须反映出来。
编辑:请注意,[last()]
相当于[position() = last()]
。
答案 1 :(得分: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元素。
答案 2 :(得分:1)
对于程序员来说,访问XML中节点的最快方法是XPath。请查看xpath methods和xpath itself。
答案 3 :(得分:0)
我认为SimpleXML无论如何都会加载整个XML(如果我没记错的话),你可以像使用数组那样使用SimpleXML节点,这样你就可以使用数组函数来获取最后一个节点。这是因为我使用PHP但你应该能够获得长度,然后获得长度为1的项目......
修改强>
你当然可以使用XPath,我想我也应该提一下,但我不确定last()
是否在SimpleXML XPath实现中有效。
我不确定哪个是最快的,使用数组索引或XPath,我猜数组索引更快但你应该在循环中尝试两次,在循环之前和之后检查时间。
但是在CS中总是如此:你选择的东西取决于很多东西。
是时间关键还是经常使用:然后找到最快的解决方案。
如果您需要更复杂的查询并且速度不是问题:那么使用最容易实现的任何内容并提供您需要的功能(XPath适用于复杂的树导航,数组索引适用于列表中的快速随机访问-type数据结构; XML可用于两者。)
答案 4 :(得分:0)
你可以从这开始..你将能够挖掘它...我不喜欢他们在2个级别使用相同的标签名称..我尽量避免重复的标签名称。
<?php
$s = simplexml_load_file('in.xml');
$s->registerXPathNamespace('obix', 'http://obix.org/ns/schema/1.0');
$items = $s->xpath('//obix:list');
?>
答案 5 :(得分: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()
获取最后一个元素,但前提是您总是有多个&lt; obj&gt;,否则会返回不同的结果。