我有一个xml如下所示,我想复制n次,同时增加一个元素和一个属性。
<?xml version="1.0"?>
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position=1>
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
</test>
</Batch>
</header>
我喜欢下面的内容,增量的数量是变量。
<?xml version="1.0"?>
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position=1>
<properties>
<name>John</name>
<number>1</number>
</properties>
</Person>
<Person position=2>
<properties>
<name>John</name>
<number>2</number>
</properties>
</Person>
...
<Person position=n>
<properties>
<name>John</name>
<number>n</number>
</properties>
</Person>
</test>
</Batch>
</header>
要解决这个问题,我已经开始使用下面的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>
有任何线索吗?
答案 0 :(得分:4)
此转化:
<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 :(得分:0)
<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>