Мой XML-файл выглядит так:
<log> <entry entry_id="E200911115777"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>1999-04-15</entry_date> </entry_data> </entry> <entry entry_id="E205011115999"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>2004-12-15</entry_date> </entry_data> </entry> <entry entry_id="E199912119116"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>1990-11-20</entry_date> </entry_data> </entry> </log>
Я ищу код, который вернет максимальное значение тега entry_date , в этом случае, 2004-12-15 . Я использую SimpleXML, но я открыт для других решений, конечно. Приветствия.
I. Вот простое решение XSLT 1.0, которое ближе всего к использованию одного выражения XPath (невозможно выбрать только одно выражение XPath 1.0, выбрав желаемый узел (узлы)):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="entry"> <xsl:copy-of select= "self::node() [not((preceding-sibling::entry | following-sibling::entry) [translate(*/entry_date,'-','') > translate(current()/*/entry_date,'-','') ] ) ] "/> </xsl:template> </xsl:stylesheet>
когда это преобразование применяется к предоставленному XML-документу :
<log> <entry entry_id="E200911115777"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>1999-04-15</entry_date> </entry_data> </entry> <entry entry_id="E205011115999"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>2004-12-15</entry_date> </entry_data> </entry> <entry entry_id="E199912119116"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>1990-11-20</entry_date> </entry_data> </entry> </log>
получается желаемый, правильный результат :
<entry entry_id="E205011115999"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>2004-12-15</entry_date> </entry_data> </entry>
II. Более эффективное решение XSLT 1.0:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/*"> <xsl:apply-templates> <xsl:sort order="descending"/> </xsl:apply-templates> </xsl:template> <xsl:template match="entry"> <xsl:if test="position() = 1"> <xsl:copy-of select="."/> </xsl:if> </xsl:template> </xsl:stylesheet>
когда это преобразование применяется к одному и тому же документу XML (см. выше), снова получается желаемый, правильный результат :
<entry entry_id="E205011115999"> <entry_data> <entry_title>Lorem ipsum dolor</entry_title> <entry_date>2004-12-15</entry_date> </entry_data> </entry>
Да, должно быть довольно легко с xpath, это определенно путь, и простой xml хорошо работает с xpath в php.
Ознакомьтесь с документами здесь: http://www.php.net/manual/en/simplexmlelement.xpath.php
$xml = new SimpleXMLElement($string); /* Search for <log><entry><entry_data><entry_date> */ $result = $xml->xpath('/log/entry/entry_data/entry_date'); while(list( , $node) = each($result)) { $timestamp = strtotime((string) $node)); echo '/log/entry/entry_data/entry_date: ' . $timestamp ."\n"; }
Я действительно не тестировал этот код, но должен быть близок к тому, что вам нужно, и временные метки, конечно, имеют свои пределы, но, похоже, подходят для вашего использования.
$result = $xml->xpath('//entry_date'); usort($result,'strcmp'); $maxdate = end($result);