Performance XSLT:在递增属性和值的同时多次复制对象xml
我有一个xml,如下所示,我想在增加一个元素和一个属性的同时复制n次 XML输入:Performance XSLT:在递增属性和值的同时多次复制对象xml,performance,xslt,grouping,Performance,Xslt,Grouping,我有一个xml,如下所示,我想在增加一个元素和一个属性的同时复制n次 XML输入: 约翰 1. 我想要下面这样的东西,增量的数量是一个变量 XML输出: 约翰 1. 约翰 2. ... 约翰 N 为了解决这个问题,我从下面的xslt开始: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="
约翰
1.
我想要下面这样的东西,增量的数量是一个变量
XML输出:
约翰
1.
约翰
2.
...
约翰
N
为了解决这个问题,我从下面的xslt开始:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pTimes" select="2"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$pTimes"/>
<xsl:with-param name="pPosition" select="1"/>
</xsl:call-template>
</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="Person">
<xsl:param name="pPosition" select="1"/>
<xsl:value-of select="$newline"/>
<Person position="{$pPosition}">
<xsl:apply-templates>
<xsl:with-param name="pPosition" select="$pPosition"/>
</xsl:apply-templates>
</Person>
</xsl:template>
<xsl:template match="number">
<xsl:param name="pPosition" select="1"/>
<number><xsl:value-of select="$pPosition"/></number>
</xsl:template>
</xsl:stylesheet>
但是输出包含元素中的名称空间。元素和属性@position始终设置为1。此外,标题环绕每个元素。
请参考以下n=2的输出
<Batch xmlns="http://test.com">
<test document="dump">
<Person position="1">
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
</test>
</Batch>
<Batch xmlns="http://test.com">
<test document="dump">
<Person position="1">
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
</test>
</Batch>
约翰
1.
约翰
1.
有什么线索吗?这个转变:
<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:test">
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$pTimes"/>
<xsl:with-param name="pPosition" select="1"/>
</xsl:call-template>
</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:Person">
<xsl:param name="pPosition" select="1"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="position">
<xsl:value-of select="$pPosition"/>
</xsl:attribute>
<xsl:apply-templates>
<xsl:with-param name="pPosition" select="$pPosition"/>
</xsl:apply-templates>
</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>
应用于提供的XML文档时:
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position="1">
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
</test>
</Batch>
</header>
<header xmlns="http://test.com">
<Batch>
<Person position="1">
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
<Person position="2">
<properties>
<name>John</name>
<number>2</number>
</properties>
</Person>
</Batch>
</header>
约翰
1.
产生想要的结果:
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position="1">
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
</test>
</Batch>
</header>
<header xmlns="http://test.com">
<Batch>
<Person position="1">
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
<Person position="2">
<properties>
<name>John</name>
<number>2</number>
</properties>
</Person>
</Batch>
</header>
约翰
1.
约翰
2.
`在这里输入代码`
使用前面给出的示例时,这其实并不难。你试过什么了吗?昨天有人问了一个类似的问题,但这个问题稍微复杂一点。在学习XSLT时,我希望尽可能多地练习。我就是找不到这个问题的解决方案。如果您有一些XSLT代码没有按照您希望的方式工作,那么请展示它,这样我们就可以从那里开始,而不是从头开始。我添加的代码没有与我看到的问题一起工作。如果您有任何线索,请告诉我。您需要了解以前问题的解决方案,以便将其应用于其他XML文档。请参阅我的答案中更新的解决方案。还有,谢谢你的尝试。很好…它很有效,但我仍然需要彻底理解这个解决方案…无论如何,它对我有很大帮助。
<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:test">
<xsl:call-template name="applyNTimes">
<xsl:with-param name="pTimes" select="$pTimes"/>
<xsl:with-param name="pPosition" select="1"/>
</xsl:call-template>
</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>`enter code here`
<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:Person">
<xsl:param name="pPosition" select="1"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="position">
<xsl:value-of select="$pPosition"/>
</xsl:attribute>
<xsl:apply-templates>
<xsl:with-param name="pPosition" select="$pPosition"/>
</xsl:apply-templates>
</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>