My XML file looks like this:
我的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>
I'm looking for code that will return the highest value of the entry_date tag, in this case, 2004-12-15. I'm using SimpleXML but I'm open to other solutions of course. Cheers.
我正在寻找将返回entry_date标记的最高值的代码,在本例中是2004-12-15。我使用的是SimpleXML,但我当然愿意接受其他的解决方案。欢呼。
3 个解决方案
#1
3
I. Here is a simple XSLT 1.0 solution that is closest to using a single XPath expression (it isn't possible to have just a single XPath 1.0 expression selecting the wanted node(s) ):
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>
when this transformation is applied on the provided XML document:
当此转换应用于所提供的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>
the wanted, correct result is produced:
所要求的正确结果如下:
<entry entry_id="E205011115999">
<entry_data>
<entry_title>Lorem ipsum dolor</entry_title>
<entry_date>2004-12-15</entry_date>
</entry_data>
</entry>
II. A more efficient XSLT 1.0 solution:
二世。更有效的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>
when this transformation is applied on the same XML document (above), again the wanted, correct result is produced:
当将此转换应用于相同的XML文档(如上)时,将再次生成所需的、正确的结果:
<entry entry_id="E205011115999">
<entry_data>
<entry_title>Lorem ipsum dolor</entry_title>
<entry_date>2004-12-15</entry_date>
</entry_data>
</entry>
#2
1
Yeah, should be quite easy with xpath, that is definately the way to go, and simple xml works well with xpath in php.
是的,使用xpath应该非常简单,这是最合适的方法,简单的xml在php中使用xpath非常有效。
Check out the docs here: http://www.php.net/manual/en/simplexmlelement.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";
}
I didn't actually test that code, but should be pretty close to what you need, and timestamps of course have their limits but seems ok for your use.
我实际上并没有测试代码,但是应该非常接近您所需要的,当然时间戳也有它们的限制,但是对于您的使用来说似乎是可以的。
#3
1
$result = $xml->xpath('//entry_date');
usort($result,'strcmp');
$maxdate = end($result);
#1
3
I. Here is a simple XSLT 1.0 solution that is closest to using a single XPath expression (it isn't possible to have just a single XPath 1.0 expression selecting the wanted node(s) ):
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>
when this transformation is applied on the provided XML document:
当此转换应用于所提供的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>
the wanted, correct result is produced:
所要求的正确结果如下:
<entry entry_id="E205011115999">
<entry_data>
<entry_title>Lorem ipsum dolor</entry_title>
<entry_date>2004-12-15</entry_date>
</entry_data>
</entry>
II. A more efficient XSLT 1.0 solution:
二世。更有效的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>
when this transformation is applied on the same XML document (above), again the wanted, correct result is produced:
当将此转换应用于相同的XML文档(如上)时,将再次生成所需的、正确的结果:
<entry entry_id="E205011115999">
<entry_data>
<entry_title>Lorem ipsum dolor</entry_title>
<entry_date>2004-12-15</entry_date>
</entry_data>
</entry>
#2
1
Yeah, should be quite easy with xpath, that is definately the way to go, and simple xml works well with xpath in php.
是的,使用xpath应该非常简单,这是最合适的方法,简单的xml在php中使用xpath非常有效。
Check out the docs here: http://www.php.net/manual/en/simplexmlelement.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";
}
I didn't actually test that code, but should be pretty close to what you need, and timestamps of course have their limits but seems ok for your use.
我实际上并没有测试代码,但是应该非常接近您所需要的,当然时间戳也有它们的限制,但是对于您的使用来说似乎是可以的。
#3
1
$result = $xml->xpath('//entry_date');
usort($result,'strcmp');
$maxdate = end($result);