Xml 按属性值排序时复制所有元素
我有这个XMLXml 按属性值排序时复制所有元素,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我有这个XML <root xmlns:temp ="temp.com"> <testNode name="a"> <sample/> </testNode> <testNode name="b"> <sample/> </testNode> <testNode name="c"> <sample/> </testNode>
<root xmlns:temp ="temp.com">
<testNode name="a">
<sample/>
</testNode>
<testNode name="b">
<sample/>
</testNode>
<testNode name="c">
<sample/>
</testNode>
<testNode name="d">
<sample/>
</testNode>
<testNode name="b">
<sample/>
</testNode>
</root>
我想编写一个转换,它可以复制所有内容,同时根据name属性的值对testNodes进行排序
预期产出为:
<root xmlns:temp ="temp.com">
<testNode name="a">
<sample/>
</testNode>
<testNode name="b">
<sample/>
</testNode>
<testNode name="b">
<sample/>
</testNode>
<testNode name="c">
<sample/>
</testNode>
<testNode name="d">
<sample/>
</testNode>
</root>
名称空间可能会让我感到厌烦,但我似乎无法对结果进行排序
到目前为止,我尝试的XSLT是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:temp="temp.com"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()">
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template name="temp:root">
<xsl:copy>
<xsl:apply-templates select="temp:testNode">
<xsl:sort select="@name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
更新
鉴于您问题中的修订信息,您当前的XSLT和源XML存在几个问题:
1)
应该是
。i、 e.您需要使用match
以要转换的元素为目标,而不是使用name
来调用模板
2) 源XML声明temp
前缀,但不使用它。你应使用:
<root xmlns="temp.com">
<testNode name="a">
<sample/>
在temp.com
名称空间中定义的元素前面加上temp
前缀
以下是XSLT对这两个问题的处理:
注意:如果希望XSLT不受名称空间的影响,还可以使用local-name()
函数
<xsl:template match="*[local-name()='root']">
<xsl:copy>
<xsl:apply-templates select="*[local-name()='testNode']">
<xsl:sort select="@name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
您可以编辑您的问题以显示您尝试过的XSLT吗?另外,您提到了名称空间,但是您在XML中声明的名称空间前缀实际上没有在任何地方使用。您的XML准确吗(也就是说,它真的是
而不仅仅是
吗?谢谢!这只是示例代码,其格式与我实际需要转换的格式类似。显示一个具有代表性的输入文档非常重要,即实际上导致您描述的问题的文档。请编辑问题。此示例的格式相同,它完美地代表了我的问题
<xsl:template match="*[local-name()='root']">
<xsl:copy>
<xsl:apply-templates select="*[local-name()='testNode']">
<xsl:sort select="@name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="utf-8" /> <!-- keeping utf 8 rather than 16 as this will be big -->
<xsl:strip-space elements="*"/>
<!-- By default, copy everything as is -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- but sort the child elements of our root element by their name attribute -->
<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="@* | node()">
<xsl:sort select="./@name" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>