我试图多次复制其中一个嵌套元素。我搜索并遇到XSLT: copy object xml multiple times while incrementing attribute and value。这很接近,但不是我要找的答案。这就是我想做的
XML输入:
<Company xmlns="http://test.com" >
<Group document="dump" >
<dump>asdfasd</dump>
<dump2>asdfasdf</dump2>
<Person>
<record>1</record>
<dump2>asdfasdf</dump2>
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
</Group>
</Company>
并输出为以下内容:
<Company xmlns="http://test.com">
<Group document="dump">
<dump>asdfasd</dump>
<dump2>asdfasdf</dump2>
<Person>
<record>1</record>
<dump2>asdfasdf</dump2>
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
...
<Person>
<record>n</record>
<dump2>asdfasdf</dump2>
<properties>
<name>John</name>
<number>n</number>
</properties>
</Person>
</Group>
</Company>
使用我的xslt:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:t="http://test.com"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pTimes" select="2"/>
<xsl:template match="node()|@*">
<xsl:param name="pPosition" select="1"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pPosition" select="$pPosition"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="t:Person">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$pTimes"/>
<xsl:with-param name="pPosition" select="1"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="applyNTimes">
<xsl:param name="pTimes" select="0"/>
<xsl:param name="pPosition" select="1"/>
<xsl:if test="$pTimes > 0">
<xsl:choose>
<xsl:when test="$pTimes = 1">
<xsl:apply-templates select="*">
<xsl:with-param name="pPosition" select="$pPosition"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vHalf" select="floor($pTimes div 2)"/>
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$vHalf"/>
<xsl:with-param name="pPosition" select="$pPosition"/>
</xsl:call-template>
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
<xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="t:record">
<xsl:param name="pPosition" select="1"/>
<xsl:copy>
<xsl:value-of select="$pPosition"/>
</xsl:copy>
</xsl:template>
<xsl:template match="t:number">
<xsl:param name="pPosition" select="1"/>
<xsl:copy>
<xsl:value-of select="$pPosition"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这就是我所拥有的
<Company xmlns="http://test.com">
<Group document="dump">
<dump>asdfasd</dump>
<dump2>asdfasdf</dump2>
<Person position="1">
<record>1</record>
<dump2>asdfasdf</dump2>
<properties>
<name>John</name>
<number>1</number>
</properties>
<record>2</record>
<dump2>asdfasdf</dump2>
<properties>
<name>John</name>
<number>2</number>
</properties>
</Person>
</Group>
</Company>
如何防止Person元素在复制时消失?
答案 0 :(得分:0)
在这种情况下,解决方案是将人的xsl:copy
从匹配t:Person
的模板中移到applyNTimes
模板中(在pTimes
为1的情况下)。
尝试使用此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://test.com" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"></xsl:output>
<xsl:strip-space elements="*"></xsl:strip-space>
<xsl:param name="pTimes" select="2"></xsl:param>
<xsl:template match="node()|@*">
<xsl:param name="pPosition" select="1"></xsl:param>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pPosition" select="$pPosition"></xsl:with-param>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="t:Person">
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$pTimes"></xsl:with-param>
<xsl:with-param name="pPosition" select="1"></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="applyNTimes">
<xsl:param name="pTimes" select="0"></xsl:param>
<xsl:param name="pPosition" select="1"></xsl:param>
<xsl:if test="$pTimes > 0">
<xsl:choose>
<xsl:when test="$pTimes = 1">
<xsl:copy>
<xsl:apply-templates select="*">
<xsl:with-param name="pPosition" select="$pPosition"></xsl:with-param>
</xsl:apply-templates>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vHalf" select="floor($pTimes div 2)"></xsl:variable>
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$vHalf"></xsl:with-param>
<xsl:with-param name="pPosition" select="$pPosition"></xsl:with-param>
</xsl:call-template>
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$pTimes - $vHalf"></xsl:with-param>
<xsl:with-param name="pPosition" select="$pPosition + $vHalf"></xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="t:record|t:number">
<xsl:param name="pPosition" select="1"></xsl:param>
<xsl:copy>
<xsl:value-of select="$pPosition"></xsl:value-of>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,如果您可以使用XSLT 2.0,则由于支持“从1到n”的构造(以及存在“隧道”功能,从而避免了必须在每个模板中显式传递参数),事情变得容易得多。 )。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:t="http://test.com"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"></xsl:output>
<xsl:strip-space elements="*"></xsl:strip-space>
<xsl:param name="pTimes" select="2"></xsl:param>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="t:Person">
<xsl:variable name="person" select="." />
<xsl:for-each select="1 to $pTimes">
<xsl:apply-templates select="$person" mode="repeat">
<xsl:with-param name="pPosition" select="position()" tunnel="yes" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="t:Person" mode="repeat">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="t:record|t:number">
<xsl:param name="pPosition" select="1" tunnel="yes"></xsl:param>
<xsl:copy>
<xsl:value-of select="$pPosition"></xsl:value-of>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>