我有一个非常不寻常的场景。从来没有听过或做过这样的事情。这是我的源XML。
<?xml version="1.0" encoding="UTF-8"?>
<ListItems>
<List>
<name>A</name>
</List>
<List>
<name>B</name>
</List>
<List>
<name>C</name>
</List>
<List>
<name>D</name>
</List>
</ListItems>
我要做的是用反向计数器作为索引来反转列表的顺序。生成的XML应如下所示:
<UpdateListItems>
<List>
<name>D</name>
<index>4</index>
</List>
<List>
<name>C</name>
<index>3</index>
</List>
<List>
<name>B</name>
<index>2</index>
</List>
<List>
<name>A</name>
<index>1</index>
</List>
</UpdateListItems>
请注意反向顺序的名称,并以相反的顺序添加索引。听起来有点愚蠢但是有可能在xml转换中做到这一点吗?
答案 0 :(得分:4)
是的,可能。使用&lt; xsl:sort&gt;将模板应用于List元素时,具有属性order =“descending”的元素。
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" >
<xsl:output method = "xml" />
<xsl:template match = "/ListItems" >
<xsl:copy>
<xsl:apply-templates select = "List" >
<xsl:sort order="descending" select="position()" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match = "node()|@*" >
<xsl:copy>
<xsl:apply-templates select = "node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match = "List" >
<xsl:copy>
<xsl:apply-templates select = "name"/>
<index><xsl:value-of select="1 + last() - position()"/></index>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
编辑:我忘了在sort元素中包含select =“position()”data-type =“number”属性
再次编辑以回答您的其他要求: 取代(正如丹尼尔已经指出的那样)
<xsl:apply-templates select = "node()|@*"/>
由此
<xsl:apply-templates select = "name"/>
或者如果您愿意,可以使用它。注意最后一个空模板,它禁止除子名称之外的任何List子项
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" >
<xsl:output method = "xml" />
<xsl:template match = "/ListItems" >
<xsl:copy>
<xsl:apply-templates select = "List" >
<xsl:sort order="descending" select="position()" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match = "node()|@*" >
<xsl:copy>
<xsl:apply-templates select = "node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match = "List" >
<xsl:copy>
<xsl:apply-templates select = "node()|@*"/>
<index><xsl:value-of select="1 + last() - position()"/></index>
</xsl:copy>
</xsl:template>
<xsl:template match="List/*[not(self::name)]"/>
</xsl:stylesheet>
答案 1 :(得分:1)
在xsl中,您可以根据位置按降序对List进行排序。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:template match="/">
<UpdatedListItems>
<xsl:for-each select="/ListItems/List/name">
<xsl:sort select="position()" data-type="number" order="descending"/>
<List>
<name><xsl:value-of select="."/></name>
</List>
</xsl:for-each>
</UpdatedListItems>
</xsl:template>
</xsl:stylesheet>
在更正后的输入(更改<name/> to </name>
)上通过xsltproc运行此操作会产生以下结果:
<UpdatedListItems><List><name>D</name></List><List><name>C</name></List><List><name>B</name></List><List><name>A</name></List></UpdatedListItems>