需要基于元素嵌套的序列号。在下面的示例中,所有不是任何引用元素的子元素的引用元素都将具有序列号,任何嵌套的引用元素都应具有父序列号+小数+当前引用元素的位置。
Input.xml中
<root>
<front>
<reference1 type="ref" href="a.xml">
<reference1 type="ref" href="x.xml"/>
<reference1 type="ref" href="z.xml"/>
</reference>
</front>
<reference2 type="ref" href="b.xml"/>
<reference2 type="ref" href="c.xml">
<reference2 type="ref" href="d.xml">
<reference2 type="ref" href="y.xml"/>
</reference>
</reference>
<back>
<reference3 type="ref" href="e.xml"/>
</back>
</root>
的Output.xml
<root>
<reference href="a.xml" sequence="1"/>
<reference href="x.xml" sequence="1.1"/>
<reference href="z.xml" sequence="1.2"/>
<reference href="b.xml" sequence="2"/>
<reference href="c.xml" sequence="3"/>
<reference href="d.xml" sequence="3.1"/>
<reference href="y.xml" sequence="3.1.1"/>
<reference href="e.xml" sequence="4"/>
</root>
我正在尝试这个但却无法得到逻辑:
<xsl:template match="/">
<root>
<xsl:for-each select="//reference">
<reference>
<xsl:attribute name="href">
<xsl:value-of select="@href"/>
</xsl:attribute>
<xsl:if test="not(child::reference)">
<xsl:attribute name="sequence">
<xsl:value-of select="position()"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="child::reference">
<!-- something to be done here -->
</xsl:if>
</reference>
</xsl:for-each>
</root>
由于
答案 0 :(得分:1)
我的建议是使用<xsl:number level="multiple"/>
为你计算。我认为,为了使计数正确,您必须将其缩小到仅reference
个元素。我可能错了,可能有一种更简单的方法,但我只有几分钟的时间花在这上面。
在我的示例中,我使用模式模板并将清理后的结果分配给变量。然后我将模板应用于该变量以进行实际转换。
这只适用于XSLT 2.0,但由于你标记了问题2.0,你应该没问题。
XML输入(添加了几个<foo/>
元素进行测试)
<root>
<front>
<reference href="a.xml">
<reference href="x.xml"/>
<reference href="z.xml"/>
</reference>
</front>
<reference href="b.xml"/>
<foo/>
<reference href="c.xml">
<reference href="d.xml">
<foo>
<reference href="y.xml"/>
</foo>
</reference>
</reference>
<back>
<reference href="e.xml"/>
</back>
</root>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="refs">
<refs>
<xsl:apply-templates select="/*//reference[not(ancestor::reference)]" mode="clean"/>
</refs>
</xsl:variable>
<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="$refs"/>
</xsl:copy>
</xsl:template>
<xsl:template match="reference">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="x">
<xsl:number level="multiple"/>
</xsl:attribute>
</xsl:copy>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="reference" mode="clean">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select=".//reference[ancestor::reference[1] is current()]" mode="clean"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML输出
<root>
<reference href="a.xml" x="1"/>
<reference href="x.xml" x="1.1"/>
<reference href="z.xml" x="1.2"/>
<reference href="b.xml" x="2"/>
<reference href="c.xml" x="3"/>
<reference href="d.xml" x="3.1"/>
<reference href="y.xml" x="3.1.1"/>
<reference href="e.xml" x="4"/>
</root>
修改强>
这是问题中更新输入的更新样式表。我只需要将reference
更改为*[@type='ref']
并将count
属性添加到xsl:number
。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="refs">
<refs>
<xsl:apply-templates select="/*//*[@type='ref'][not(ancestor::*[@type='ref'])]" mode="clean"/>
</refs>
</xsl:variable>
<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="$refs"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@type='ref']">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="x">
<xsl:number count="*[@type='ref']" level="multiple"/>
</xsl:attribute>
</xsl:copy>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[@type='ref']" mode="clean">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select=".//*[@type='ref'][ancestor::*[@type='ref'][1] is current()]" mode="clean"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>