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

求助:使用XSLT将同级节点XML转换为父子分组结构

处理同级Result_HEADER与交易节点的XSLT方案

嘿,刚上手XSLT碰到这种节点布局确实有点挠头——明明是一组的节点却被放在同级,没关系,咱们用XSLT的节点轴和模板匹配就能轻松把它们归拢到一起。

首先得明确咱们的目标:把每个Result_HEADER和它对应的Result_Y、Result_Addendum(紧跟在Header后面的同级节点)包装成一个逻辑上的交易组,让结构更清晰。

第一步:处理命名空间

你的原始XML带有默认命名空间http://peak.company.com,所以XSLT里必须正确声明这个命名空间,不然根本匹配不到节点。咱们可以用xpath-default-namespace属性来简化操作,不用给每个节点加前缀。

完整XSLT代码示例

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xpath-default-namespace="http://peak.company.com">

  <!-- 匹配根节点,初始化输出结构 -->
  <xsl:template match="/Peak">
    <Peak>
      <xsl:copy-of select="OffTime"/> <!-- 保留原有的OffTime节点 -->
      <!-- 遍历所有Result_HEADER节点,每个Header对应一组交易数据 -->
      <xsl:for-each select="Result_HEADER">
        <Transaction>
          <!-- 复制当前Header节点 -->
          <xsl:copy-of select="."/>
          <!-- 获取紧跟在当前Header后面的第一个Result_Y节点 -->
          <xsl:copy-of select="following-sibling::Result_Y[1]"/>
          <!-- 获取紧跟在当前Header后面的第一个Result_Addendum节点 -->
          <xsl:copy-of select="following-sibling::Result_Addendum[1]"/>
        </Transaction>
      </xsl:for-each>
    </Peak>
  </xsl:template>

  <!-- 匹配其他未处理的节点,默认复制(如果需要保留其他节点的话) -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

代码关键点解释

  • xpath-default-namespace="http://peak.company.com":告诉XSLT,所有不带前缀的XPath表达式默认使用这个命名空间,不用每次写prefix:Result_HEADER这种繁琐形式。
  • following-sibling::Result_Y[1]:使用following-sibling轴获取当前节点后面的同级节点,[1]确保只取第一个匹配的Result_Y,刚好对应当前Header的交易详情。
  • <Transaction>:咱们自定义的包装节点,把一组Header和交易节点归在一起,让输出结构更符合逻辑。

转换后的示例输出

假设原始XML是:

<?xml version="1.0" encoding="UTF-8"?>
<Peak xmlns="http://peak.company.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <OffTime>2024-05-20</OffTime>
  <Result_HEADER>
    <Suffix>001</Suffix>
    <Status>Success</Status>
  </Result_HEADER>
  <Result_Y>
    <Amount>100.00</Amount>
    <Date>2024-05-20</Date>
  </Result_Y>
  <Result_Addendum>
    <Note>First transaction</Note>
  </Result_Addendum>
  <Result_HEADER>
    <Suffix>002</Suffix>
    <Status>Success</Status>
  </Result_HEADER>
  <Result_Y>
    <Amount>200.00</Amount>
    <Date>2024-05-21</Date>
  </Result_Y>
  <Result_Addendum>
    <Note>Second transaction</Note>
  </Result_Addendum>
</Peak>

转换后会变成:

<?xml version="1.0" encoding="UTF-8"?>
<Peak xmlns="http://peak.company.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <OffTime>2024-05-20</OffTime>
  <Transaction>
    <Result_HEADER>
      <Suffix>001</Suffix>
      <Status>Success</Status>
    </Result_HEADER>
    <Result_Y>
      <Amount>100.00</Amount>
      <Date>2024-05-20</Date>
    </Result_Y>
    <Result_Addendum>
      <Note>First transaction</Note>
    </Result_Addendum>
  </Transaction>
  <Transaction>
    <Result_HEADER>
      <Suffix>002</Suffix>
      <Status>Success</Status>
    </Result_HEADER>
    <Result_Y>
      <Amount>200.00</Amount>
      <Date>2024-05-21</Date>
    </Result_Y>
    <Result_Addendum>
      <Note>Second transaction</Note>
    </Result_Addendum>
  </Transaction>
</Peak>

如果你的实际场景里每个Header对应多个交易节点,还可以调整following-sibling的匹配条件,比如用following-sibling::Result_Y[preceding-sibling::Result_HEADER[1] = current()]来精准绑定属于当前Header的所有交易节点,不过从你的描述来看,一对一的场景用上面的代码就完全够用啦。

内容的提问来源于stack exchange,提问作者Phil B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:34:21