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

XSL-FO合并不同节点两行内容求助:XML与FOP技术问题咨询

解决XSL-FO合并XML不同节点内容的问题

嘿,我来帮你搞定XSL-FO合并XML节点内容的问题!从你给出的XML片段来看,你有多个<PartDtl>节点,想要把不同节点里的内容合并成一行对吧?下面我给你两种常见场景的实用解决方案,你可以根据实际需求调整:

场景1:按相同属性分组合并(比如同RepTyp的节点)

如果你的需求是把所有RepTyp相同的<PartDtl>内容合并成一行,用XSLT的分组功能就能轻松实现。这里用<xsl:key>来分组,再在XSL-FO里输出合并后的内容:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" indent="yes"/>

  <!-- 定义分组规则:按RepTyp字段分组 -->
  <xsl:key name="partByRepTyp" match="PartDtl" use="RepTyp"/>

  <xsl:template match="/selectedcalculation/CLASSXml/CalcData/SpareParts">
    <fo:root>
      <!-- 定义页面布局 -->
      <fo:layout-master-set>
        <fo:simple-page-master master-name="page" page-width="210mm" page-height="297mm">
          <fo:region-body margin="20mm"/>
        </fo:simple-page-master>
      </fo:layout-master-set>

      <fo:page-sequence master-reference="page">
        <fo:flow flow-name="xsl-region-body">
          <!-- 遍历每个唯一的RepTyp分组 -->
          <xsl:for-each select="PartDtls/PartDtl[generate-id() = generate-id(key('partByRepTyp', RepTyp)[1])]">
            <fo:block font-size="14pt" font-weight="bold" margin-bottom="5mm">
              维修类型: <xsl:value-of select="RepTyp"/>
            </fo:block>
            <!-- 合并输出该分组下的所有零件信息 -->
            <fo:block margin-bottom="10mm" font-size="12pt">
              <xsl:for-each select="key('partByRepTyp', RepTyp)">
                <!-- 给除第一个外的内容加分隔符 -->
                <xsl:if test="position() > 1"> | </xsl:if>
                <xsl:value-of select="PartDesc"/> (<xsl:value-of select="PartNo"/>) - <xsl:value-of select="Price"/>
              </xsl:for-each>
            </fo:block>
          </xsl:for-each>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
</xsl:stylesheet>

这段代码会把所有RepTyp为E的零件信息合并成一行,用|分隔,排版成清晰的块级内容。

场景2:合并指定节点的内容(比如特定GId的节点)

如果你的需求是合并特定几个节点(比如GId为0281和0471的零件),可以直接通过变量定位节点,再把它们的字段拼接起来,甚至可以做数值计算:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/selectedcalculation/CLASSXml/CalcData/SpareParts">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master master-name="page" page-width="210mm" page-height="297mm">
          <fo:region-body margin="20mm"/>
        </fo:simple-page-master>
      </fo:layout-master-set>

      <fo:page-sequence master-reference="page">
        <fo:flow flow-name="xsl-region-body">
          <!-- 定位要合并的两个节点 -->
          <xsl:variable name="frontBumper" select="PartDtls/PartDtl[GId='0281']"/>
          <xsl:variable name="otherPart" select="PartDtls/PartDtl[GId='0471']"/>

          <!-- 合并输出内容,还可以计算总价 -->
          <fo:block font-size="12pt" line-height="1.5">
            合并零件: <xsl:value-of select="$frontBumper/PartDesc"/> + <xsl:value-of select="$otherPart/PartDesc"/>
            <fo:block>零件编号: <xsl:value-of select="$frontBumper/PartNo"/> & <xsl:value-of select="$otherPart/PartNo"/></fo:block>
            <fo:block font-weight="bold">
              总价: <xsl:value-of select="number(substring($frontBumper/Price,2)) + number(substring($otherPart/Price,2))"/> HRK
            </fo:block>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
</xsl:stylesheet>

这里通过substring去掉Price里的+号,转成数值后计算总价,非常实用。

额外提示

如果你的合并规则是其他情况(比如按零件编号前缀、相邻节点合并),只需要调整XSLT里的选择器或分组逻辑就行。另外,XSL-FO部分可以根据你的排版需求,调整字体、间距、表格布局等样式。

内容的提问来源于stack exchange,提问作者Zoran Maćešić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:22:59