如何使用 SimpleXML 获取 XML 文件中特定标签的最高值?

发布于 2024-10-12 10:46:27 字数 863 浏览 5 评论 0原文

我的 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,但当然我也愿意接受其他解决方案。干杯。

My XML file looks like this:

<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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

看春风乍起 2024-10-19 10:46:27

我。下面是一个最接近使用单个 XPath 表达式的简单 XSLT 1.0 解决方案(不可能仅使用单个 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>

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) ):

<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:

<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:

<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:

<entry entry_id="E205011115999">
   <entry_data>
      <entry_title>Lorem ipsum dolor</entry_title>
      <entry_date>2004-12-15</entry_date>
   </entry_data>
</entry>
鲜血染红嫁衣 2024-10-19 10:46:27

是的,使用 xpath 应该很容易,这绝对是要走的路,简单的 xml 与 php 中的 xpath 配合得很好。

查看此处的文档:
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";
}

我实际上并没有测试该代码,但应该非常接近您所需要的,并且时间戳当然有其限制,但似乎适合您的使用。

Yeah, should be quite easy with xpath, that is definately the way to go, and simple xml works well with xpath in php.

Check out the docs here:
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.

吃素的狼 2024-10-19 10:46:27
$result = $xml->xpath('//entry_date');

usort($result,'strcmp');

$maxdate = end($result);
$result = $xml->xpath('//entry_date');

usort($result,'strcmp');

$maxdate = end($result);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文