XSLT 1.0:将XML中同一<cd>元素值合并到单个<fo:block>中
解决XSLT 1.0合并多个元素值到单个fo:block的问题
原XML示例
<root> <child-A> <element> <cd>CD1</cd> <cd>CD2</cd> <cd>CD3</cd> </element> </child-A> </root>
原XSLT代码(仅获取第一个的值)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:template match="/"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="page" page-width="8.5in" page-height="11in"> <fo:region-body margin="1in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="page"> <fo:flow flow-name="xsl-region-body"> <fo:block> <xsl:value-of select="child-A/element/cd"/> </fo:block> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> </xsl:stylesheet>
当前输出(仅包含第一个的值)
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="page" page-width="8.5in" page-height="11in"> <fo:region-body margin="1in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="page"> <fo:flow flow-name="xsl-region-body"> <fo:block>CD1</fo:block> </fo:flow> </fo:page-sequence> </fo:root>
期望输出(合并所有的值到单个fo:block)
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="page" page-width="8.5in" page-height="11in"> <fo:region-body margin="1in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="page"> <fo:flow flow-name="xsl-region-body"> <fo:block>CD1, CD2, CD3</fo:block> </fo:flow> </fo:page-sequence> </fo:root>
解决方案
XSLT 1.0中xsl:value-of默认仅提取匹配节点集的第一个节点文本值,要合并所有<cd>内容,可使用以下两种方法:
方法1:使用<xsl:for-each>遍历输出(简单直接)
修改原<fo:block>内的代码,遍历所有child-A/element/cd节点,逐个输出文本并添加分隔符(避免末尾多余分隔符):
<fo:block> <xsl:for-each select="child-A/element/cd"> <xsl:value-of select="."/> <!-- 仅在非最后一个节点后添加分隔符 --> <xsl:if test="position() != last()">, </xsl:if> </xsl:for-each> </fo:block>
方法2:递归模板合并(灵活复用)
如果需要复用合并逻辑或自定义分隔规则,可编写递归模板:
<!-- 定义递归合并模板 --> <xsl:template name="join-cds"> <xsl:param name="cd-nodes"/> <xsl:param name="separator" select="', '"/> <xsl:if test="$cd-nodes"> <xsl:value-of select="$cd-nodes[1]"/> <xsl:if test="count($cd-nodes) > 1"> <xsl:value-of select="$separator"/> <xsl:call-template name="join-cds"> <xsl:with-param name="cd-nodes" select="$cd-nodes[position() > 1]"/> <xsl:with-param name="separator" select="$separator"/> </xsl:call-template> </xsl:if> </xsl:if> </xsl:template> <!-- 在fo:block中调用模板 --> <fo:block> <xsl:call-template name="join-cds"> <xsl:with-param name="cd-nodes" select="child-A/element/cd"/> </xsl:call-template> </fo:block>
内容的提问来源于stack exchange,提问作者priyanka manogaran
相关产品推荐
相关产品推荐

