考虑以下“ sample.xml”
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<level>
<name>testA</name>
<level>
<name>testB</name>
</level>
<level>
<name>testC</name>
<level>
<name>testD</name>
<level>
<name>testE</name>
</level>
</level>
</level>
</level>
</root>
使用xmlstarlet我可以做到:
xml sel -t -m //level -v name -o " " -v "count(ancestor::*)-1" -o "." -v "count(preceding-sibling::*)" -n sample.xml
这产生了:
testA 0.0
testB 1.1
testC 1.2
testD 2.1
testE 3.1
我应该怎么做:
testA 0.0
testB 1.1
testC 1.2
testD 1.2.1
testE 1.2.1.1
在此示例中,我只有4个级别,但是可以大于4。
我正在考虑某种递归,有没有可用的链接可以解释如何做到这一点?
您应该能够通过XSLT和"tr" command in xmlstarlet ...来执行此操作>
但是您想要的输出有些混乱。如果“ testA”是第一级并且您从零开始,为什么其他所有条目都不从零开始?也许“根”应该为零?
无论如何,这是一个从1开始而不是从0开始的示例,应该可以让您入门...
XML输入
(input.xml)<root>
<level>
<name>testA</name>
<level>
<name>testB</name>
</level>
<level>
<name>testC</name>
<level>
<name>testD</name>
<level>
<name>testE</name>
</level>
</level>
</level>
</level>
</root>
XSLT 1.0
(test.xsl)<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="level">
<xsl:value-of select="concat(name, ' ')"/>
<xsl:for-each select="ancestor-or-self::level">
<xsl:if test="not(position()=1)">.</xsl:if>
<xsl:number/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="level"/>
</xsl:template>
</xsl:stylesheet>
命令行
xmlstarlet tr test.xsl input.xml
输出
testA 1
testB 1.1
testC 1.2
testD 1.2.1
testE 1.2.1.1