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

XSLT如何循环InvoiceLine,将关联Charge与Quantity同行输出?

XML/XSLT关联Charge与Quantity配对输出解决方案

问题场景

现有如下XML结构:

<cac:InvoiceLine>
    <cbc:ID>1</cbc:ID>
    <cbc:Note>Some remark text</cbc:Note>
    <cbc:Note>Charge: 1234567*</cbc:Note>
    <cbc:Note>Quantity: 1000*</cbc:Note>
    <cbc:Note>Charge: 987654*</cbc:Note>
    <cbc:Note>Quantity: 5000*</cbc:Note>
    ...
</cac:InvoiceLine>

其中Charge与Quantity按顺序配对关联(如Charge: 1234567*对应Quantity: 1000*),需要将每对数据输出为以下单行格式:

1000 kg Charge 1234567
5000 kg Charge 987654

用户原代码会为每个<cbc:Note>单独换行,无法实现配对输出:

<xsl:for-each select="./cbc:Note">
  <xsl:choose>
    <xsl:when test="contains(.,'Charge:')">
      <xsl:value-of select="substring-before(substring-after(.,'Charge:'),'*')"/>
      <br />
    </xsl:when>
    <xsl:when test="contains(.,'Menge:')">
      <xsl:value-of select="substring-before(substring-after(.,'Quantity:'),'*')"/>
      <br />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="."/>
      <br />
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each>

解决思路

思路1:遍历Charge节点,关联后续首个Quantity节点

利用节点的顺序关系,遍历所有Charge类型的<cbc:Note>,然后获取每个Charge节点之后的第一个Quantity节点,实现配对输出:

<!-- 遍历所有包含Charge的Note节点 -->
<xsl:for-each select="cbc:Note[contains(., 'Charge:')]">
  <!-- 提取Charge的数值 -->
  <xsl:variable name="chargeVal" select="substring-before(substring-after(., 'Charge: '), '*')"/>
  <!-- 获取当前Charge节点之后第一个Quantity节点的数值 -->
  <xsl:variable name="qtyVal" select="following-sibling::cbc:Note[contains(., 'Quantity: ')][1]/substring-before(substring-after(., 'Quantity: '), '*')"/>
  
  <!-- 输出配对后的单行内容 -->
  <xsl:value-of select="concat($qtyVal, ' kg Charge ', $chargeVal)"/>
  <br/>
</xsl:for-each>

思路2:按位置索引分组配对

如果Charge和Quantity是严格交替出现的,可以通过位置索引直接配对对应位置的节点:

<!-- 遍历所有Charge节点 -->
<xsl:for-each select="cbc:Note[contains(., 'Charge:')]">
  <xsl:variable name="currentIndex" select="position()"/>
  <!-- 提取对应位置的Quantity节点数值 -->
  <xsl:variable name="qtyVal" select="../cbc:Note[contains(., 'Quantity:')][$currentIndex]/substring-before(substring-after(., 'Quantity: '), '*')"/>
  <xsl:variable name="chargeVal" select="substring-before(substring-after(., 'Charge: '), '*')"/>
  
  <xsl:value-of select="concat($qtyVal, ' kg Charge ', $chargeVal)"/>
  <br/>
</xsl:for-each>

补充优化

  • 注意文本匹配的空格:原XML中Charge: 和Quantity: 带有空格,提取数值时要保留该空格,避免获取到带空格的无效值。
  • 若存在未配对的Charge/Quantity节点,可以添加判断逻辑避免输出空内容:
<xsl:if test="$qtyVal != '' and $chargeVal != ''">
  <xsl:value-of select="concat($qtyVal, ' kg Charge ', $chargeVal)"/>
  <br/>
</xsl:if>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:17:24