xpath - 建立“目录”
问题描述
考虑以下'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 和xmlstarlet 中的“tr”命令来执行此操作...
但是,您想要的输出有点令人困惑。如果“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
推荐阅读
- python - 我的列表正在更改,我不知道为什么
- java - 向 arrayList 添加标记会导致应用程序崩溃
- python - 如何在python中概率性地填充列表?
- twitter-bootstrap - 无法在引导卡中添加两列
- python - 在 sympy 中生成一个多变量多项式
- reactjs - 用 redux 命名导出?
- php - 如何获得完全解码的字符串
- android - 发生 Selendroid webdriver 初始化错误
- swift - 迅速。使地图视图注释平滑过渡到新的注释视图
- angular - 失败:需要对条件“匹配 DocumentNode”进行一次匹配操作,但没有找到