我试图通过使用XSLT组合属性的值来展平嵌套XML元素的树。例如,如果我有以下输入:
<node value="a">
<node value="b">
<node value="c">
<node value="d">
</node>
</node>
<node value="e">
<node value="f">
</node>
<node value="g">
<node value="h">
</node>
</node>
</node>
</node>
</node>
然后这些将是&#34;扁平化的&#34;结果我希望能够得到:
a/b/c/d
a/b/e/f
a/b/e/g/h
我目前所能实现的只是在最深层嵌套的节点&#34;节点&#34;上输出记录。用&#34;值&#34;属性:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:csv="csv:csv">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="text()|@*"/>
<xsl:template match="node[@value]">
<xsl:if test="not(descendant::node[@value])">
<xsl:value-of select="@value"/>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
正如您从我的描述和xsl:if
测试中收集到的那样,一个潜在的复杂因素是&#34;节点&#34;元素可能没有&#34;值&#34;属性,所以必须明确检查。如何更新此样式表以获得所需的结果?
答案 0 :(得分:2)
使用XSLT 2或3,它变为
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="descendant::node[@value and not(descendant::node[@value])]!string-join(ancestor-or-self::node/@value, '/')" separator=" "/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/b4GWVh/0
使用XSLT 1我会使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="descendant::node[@value and not(descendant::node[@value])]"/>
</xsl:template>
<xsl:template match="node">
<xsl:apply-templates select="ancestor-or-self::node/@value"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="@value">
<xsl:if test="position() > 1">/</xsl:if>
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>