建立“目录”

问题描述 投票:3回答:1

考虑以下“ 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。

我正在考虑某种递归,有没有可用的链接可以解释如何做到这一点?

xpath xmlstarlet
1个回答
0
投票

您应该能够通过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>&#xA;</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
© www.soinside.com 2019 - 2024. All rights reserved.