PHP SimpleXML. Как получить последний товар?

Как я могу получить последний объект (или любой конкретный элемент) в объекте 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> (или даже его часть).

Используйте функцию last() XPath, которая решает эту проблему:

 <?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 должен отражать это.


EDIT: Обратите внимание, что [last()] эквивалентно [position() = last()] .

Существует выражение 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()] выберет последний элемент книги, являющийся дочерним элементом элемента книжного магазина.

Самый быстрый способ доступа к узлам в XML для программиста – XPath. Взгляните на методы xpath и xpath .

Вы можете начать с этого .. Вы сможете выкопать его. Мне не нравится, что они использовали одно и то же имя тега на 2 уровнях. Я стараюсь избегать дублирования имен тегов.

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

Я думаю, что SimpleXML все равно загружает весь XML и (если я правильно помню) вы можете использовать узлы SimpleXML, как если бы они были массивами, поэтому вы могли просто использовать функции массива для получения последнего узла. Это время, так как я использовал PHP, но вы должны иметь возможность получить длину, а затем получить элемент длиной 1 …

Редактирование. Конечно, вы можете использовать XPath, я думал, что должен упомянуть об этом, но я не был уверен, что last() работал в реализации SimpleXML XPath.

Я не уверен, что быстрее, используя индексы массивов или XPath, я бы предположил, что индексы массивов были быстрее, но вы должны попробовать оба в цикле несколько тысяч раз получить время до и после цикла для проверки.

Но как всегда в CS: то, что вы выбираете, зависит от многих вещей.

Это время критично или используется очень часто: затем найдите самое быстрое решение.

Если вам потребуются более сложные запросы, и скорость не является проблемой: используйте то, что проще всего реализовать и дает необходимую вам мощность (XPath хорош для сложной навигации по дереву, индексирование массива полезно для быстрого произвольного доступа в структурах типов списка , XML может использоваться для обоих.)

Как уже упоминалось, вы можете использовать обозначения и функции массива.

  <?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>, иначе он вернет другой результат.