You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于XSLT 1.0提取XML中value1最大值对应的Test节点

XSLT 1.0筛选value1最大值对应的Test节点

我正在编写XSLT 1.0样式表,需要处理如下XML:从所有<Test>节点中找出value1字段值最大的节点,输出该节点下所有子标签,同时保留原XML的根结构。

请求XML

<?xml version="1.0" encoding="UTF-8"?>
<GetTestValues xmlns="http://www.test.com/GetTestValues">
  <TestSample>
    <Test>
      <value1>10000</value1>
      <value2>2016-01-28</value2>
      <value3>2017-12-10T01:36:12.403+00:00</value3>
      <value4>US</value4>
      <value5>true</value5>
    </Test>
    <Test>
      <value1>30000</value1>
      <value2>2019-01-28</value2>
      <value3>2019-01-28T18:04:13.763+00:00</value3>
      <value4>Canada</value4>
      <value5>false</value5>
    </Test>
    <Test>
      <value1>50000</value1>
      <value2>2019-01-28</value2>
      <value3>2019-01-28T18:04:13.763+00:00</value3>
      <value4>Canada</value4>
      <value5>false</value5>
    </Test>
  </TestSample>
</GetTestValues>

期望输出

<?xml version="1.0" encoding="UTF-8"?>
<GetTestValues xmlns="http://www.test.com/GetTestValues">
  <TestSample>
    <Test>
      <value1>50000</value1>
      <value2>2019-01-28</value2>
      <value3>2019-01-28T18:04:13.763+00:00</value3>
      <value4>Canada</value4>
      <value5>false</value5>
    </Test>
  </TestSample>
</GetTestValues>

尝试的代码及问题

我尝试用<xsl:for-each>遍历所有Test节点,但会输出全部内容,不知道如何比较并筛选出value1值最大的节点。尝试的代码如下:

<xsl:for-each select="/ns0:GetTestValues/ns0:TestSample/ns0:Test">
  <ns0:value1>
    <xsl:value-of select="ns0:value1"/>
  </ns0:value1>
  <ns0:value2>
    <xsl:value-of select="ns0:value2"/>
  </ns0:value2>
  <ns0:value3>
    <xsl:value-of select="ns0:value3"/>
  </ns0:value3>
  <ns0:value4>
    <xsl:value-of select="ns0:value4"/>
  </ns0:value4>
  <ns0:value5>
    <xsl:value-of select="ns0:value5"/>
  </ns0:value5>
</xsl:for-each>

解决方案

XSLT 1.0没有内置的max()函数,可通过以下两种方法实现需求:

方法1:排序后取首个节点

利用<xsl:sort>对Test节点按value1降序排序,仅输出第一个节点:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns0="http://www.test.com/GetTestValues">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

  <xsl:template match="/ns0:GetTestValues">
    <ns0:GetTestValues>
      <ns0:TestSample>
        <xsl:for-each select="ns0:TestSample/ns0:Test">
          <!-- 按value1数字值降序排序 -->
          <xsl:sort select="ns0:value1" data-type="number" order="descending"/>
          <!-- 只保留第一个排序后的节点 -->
          <xsl:if test="position() = 1">
            <xsl:copy-of select="."/>
          </xsl:if>
        </xsl:for-each>
      </ns0:TestSample>
    </ns0:GetTestValues>
  </xsl:template>
</xsl:stylesheet>

方法2:用节点谓词直接筛选

通过谓词判断当前节点的value1是否大于等于所有其他Test节点的value1:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns0="http://www.test.com/GetTestValues">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

  <xsl:template match="/ns0:GetTestValues">
    <ns0:GetTestValues>
      <ns0:TestSample>
        <!-- 筛选value1为最大值的Test节点 -->
        <xsl:copy-of select="ns0:TestSample/ns0:Test[ns0:value1 >= ../ns0:Test/ns0:value1]"/>
      </ns0:TestSample>
    </ns0:GetTestValues>
  </xsl:template>
</xsl:stylesheet>

关键说明

  • 必须正确绑定命名空间ns0,对应原XML的http://www.test.com/GetTestValues;
  • 排序时指定data-type="number",避免字符串排序导致的错误(如"10000"字符串排序会落后于"5000");
  • 方法1直观易懂,适合节点数量较少的场景;方法2无需排序,性能更优。

内容的提问来源于stack exchange,提问作者Krishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:04:58