我有一个包含大量行节点的大型xml文件。我想按每行的id值对其进行排序。
所以这将是一个示例输入:
<database>
<table>
<row>
<id>10</id>
<foo>bar</foo>
</row>
<row>
<id>5</id>
<foo>poit</foo>
</row>
<row>
<id>1</id>
<foo>narf</foo>
</row>
</table>
</database>
这是预期的输出:
<database>
<table>
<row>
<id>1</id>
<foo>narf</foo>
</row>
<row>
<id>5</id>
<foo>poit</foo>
</row>
<row>
<id>10</id>
<foo>bar</foo>
</row>
</table>
</database>
我怎样才能实现这一目标?我有xmlstarlet
可供我使用。它具有transform,并且我可以在xsl文件中提供xslt样式表。
我之前没有使用xslt,也不确定如何继续。
我发现some related sorting questions提供了一些XSLT示例,但我无法让它们在我的用例中工作。
我当前的sort.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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*">
<xsl:sort select="row()"/>
</xsl:apply-templates>
<xsl:apply-templates select="node()">
<xsl:sort select="id()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
然而它失败了:
$ xmlstarlet tr sort.xsl example.xml
Invalid number of arguments
xmlXPathCompiledEval: evaluation failed
Invalid number of arguments
xmlXPathCompiledEval: evaluation failed
Invalid number of arguments
xmlXPathCompiledEval: evaluation failed
<database>
<table/>
</database>
答案 0 :(得分:2)
我对xmlstarlet一无所知,但我可以说你的XSLT应该真的像这样......
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table">
<xsl:copy>
<xsl:apply-templates select="row">
<xsl:sort select="id" data-type="number" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
注意XSLT中元素名称后面不需要()
。
在http://xsltransform.net/pNmBy1b
中查看此操作(我还注意到标记xmlstarlet
只有20个关注者。您可能想要尝试其他一些工具。请参阅https://stackoverflow.com/tags/xslt/info以获得一些帮助。也许是xsltproc?)