我是使用xsl的新手,我不确定如何删除特定的父节点及其所有子节点(如果全部为空)。我认为link中显示的答案是我所需要的,但是我不确定如何将其应用于特定节点而不是整个样式表。
使用该问题中的内容,我将其扩展了...
<farm>
<foo>
<bar>
<baz/>
</bar>
<quux> </quux>
<quuux>Actual content</quuux>
</foo>
<sounds>
<moo>
<meow>
<buzz></buzz>
</meow>
</moo>
<birds>
<cluck> </cluck>
<quack></quack>
</birds>
</sounds>
</farm>
我如何消除<sounds>
及其所有子级(如果它们全部为空),而又留下诸如foo,bar和baz之类的空节点。我正在生成的xml的需求即使它们为空白也需要具有某些标记,但是如果它们为空白,则需要将其删除。
走得更远,如果我拥有的是...
<farm>
<foo>
<bar>
<baz/>
</bar>
<quux> </quux>
<quuux>Actual content</quuux>
</foo>
<sounds>
<moo>
<meow>
<buzz>"zzzz"</buzz>
</meow>
</moo>
<birds>
<cluck> </cluck>
<quack></quack>
</birds> <!-- Fixed by edit -->
</sounds>
</farm>
在此示例中,<sounds>, <moo>, <meow>
和<buzz>
将需要保留,因为<buzz>
具有值,但是<birds>
及其子项将被删除。
在我看来,这是如此复杂,我不确定最简单的方法是什么。
非常感谢您的指导,因为我走了这么多圈子感到头晕目眩!
答案 0 :(得分:1)
如果您的处理器不支持XSLT 3.0,这是XSLT 1.0选项...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[ancestor-or-self::sounds][not(string())]"/>
</xsl:stylesheet>
例如#1的小提琴:http://xsltfiddle.liberty-development.net/jyH9rNp
以小提琴为例#2:http://xsltfiddle.liberty-development.net/jyH9rNp/1
答案 1 :(得分:0)
假设XSLT 3(受Saxon 9.8和9.9的Java平台以及受Saxon 9.8的.NET平台支持,以及Altova 2017/2018/2019也受支持),则可以将xsl:where-populated
与{{1}一起使用} xsl:next-match
和其他任何后代元素以及其余的身份转换;另外,您将需要去除空格,否则sounds
不会被删除:
<cluck> </cluck>
https://xsltfiddle.liberty-development.net/gWmuiKn/0是您的第一个输入,而https://xsltfiddle.liberty-development.net/gWmuiKn/1是您的第二个输入。