Xslt XSL为每个子节点重复父节点
对于每个子节点,我希望复制父节点,以便生成的xml只包含父节点的一个子节点,其他节点相同 这是一个示例输入Xslt XSL为每个子节点重复父节点,xslt,Xslt,对于每个子节点,我希望复制父节点,以便生成的xml只包含父节点的一个子节点,其他节点相同 这是一个示例输入 <a> <a1>header1</a1> <a2>header2</a2> <a3> <a31> <a311>line_1</a311> <a311>line_2</a311> </
<a>
<a1>header1</a1>
<a2>header2</a2>
<a3>
<a31>
<a311>line_1</a311>
<a311>line_2</a311>
</a31>
<a32>5o$</a32>
<a33>Add</a33>
</a3>
<a4>account_holder</a4>
</a>
校长1
校长2
第1行
第2行
5o$
添加
账户持有人
我想做的是——在节点a311出现时重复a3多次。Rest保留所有节点
输出
<a>
<a1>header1</a1>
<a2>header2</a2>
<a3>
<a31>
<a311>line_1</a311>
</a31>
<a32>5o$</a32>
<a33>Add</a33>
</a3>
<a3>
<a31>
<a311>line_2</a311>
</a31>
<a32>5o$</a32>
<a33>Add</a33>
</a3>
<a4>account_holder</a4>
</a>
校长1
校长2
第1行
5o$
添加
第2行
5o$
添加
账户持有人
您没有指定XSLT版本。下面是一个XSLT2样式表,它将实现您想要的功能:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a3" mode="#default">
<xsl:apply-templates select="a31/a311"/>
</xsl:template>
<xsl:template match="a311">
<xsl:apply-templates select="../.." mode="x">
<xsl:with-param name="label" select="text()"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="a3" mode="x">
<xsl:param name="label"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<a31>
<a311><xsl:value-of select="$label"/></a311>
</a31>
<xsl:apply-templates select="* except a31"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
它使用身份转换来通过“无趣”元素,同时捕获
节点并应用特殊处理。如果需要XSLT1解决方案,只需
- 用
select=“*[name()!='a31']”替换
select=“*[name()!='a31']”
- 删除第一个“a3”模板中的
mode=“#default”
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="a3">
<xsl:apply-templates select="a31/a311" />
</xsl:template>
<xsl:template match="a311">
<a3>
<a31>
<a311>
<xsl:value-of select="." />
</a311>
</a31>
<xsl:apply-templates select="../../*[not(self::a31)]" />
</a3>
</xsl:template>
</xsl:stylesheet>
更多“隧道参数”模式的语义,此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()" name="identity">
<xsl:param name="pCurrent"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="pCurrent" select="$pCurrent"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="a3">
<xsl:variable name="vCurrent" select="."/>
<xsl:variable name="vDescendants" select=".//a311"/>
<xsl:for-each select="$vDescendants|$vCurrent[not($vDescendants)]">
<xsl:variable name="vDescendant" select="."/>
<xsl:for-each select="$vCurrent">
<xsl:call-template name="identity">
<xsl:with-param name="pCurrent" select="$vDescendant"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="a311">
<xsl:param name="pCurrent"/>
<xsl:if test="generate-id()=generate-id($pCurrent)">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出:
<a>
<a1>header1</a1>
<a2>header2</a2>
<a3>
<a31>
<a311>line_1</a311>
</a31>
<a32>5o$</a32>
<a33>Add</a33>
</a3>
<a3>
<a31>
<a311>line_2</a311>
</a31>
<a32>5o$</a32>
<a33>Add</a33>
</a3>
<a4>account_holder</a4>
</a>
校长1
校长2
第1行
5o$
添加
第2行
5o$
添加
账户持有人
编辑:不处理子体大小写。当您键入它时,它最初看起来像XML吗?因为它没有显示为XML。是否仅在子元素具有相同名称时才执行此操作?e、 g.在您的示例中,a311元素。您还复制了a3元素,它不是a311元素的父元素。我认为您需要更清楚地了解要将其应用于哪个级别、沿轴向下多远以及使用哪些规则。我曾在类似的情况下尝试过此方法,但它在输出中产生了太多的换行符。