我正在尝试删除所有满足条件的元素节点,然后删除父节点(如果仍然没有子节点)。
我成功删除了所有满足我条件的孩子,但不知道如何删除仍然为空的父母。
<root>
<parent>
<childA>
<grandchildX>03</grandchildX>
<grandchildY>02</grandchildY>
</childA>
</parent>
</root>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="childA[grandchildX[text()='03']][grandchildY[text()='02']]"/>
</xsl:stylesheet>
当XSLT样式表具有除<parent>
以外的其他子项(例如<childA>
)时,XSLT样式表必须输出<childB>
(这已经有效)。
答案 0 :(得分:2)
使用XSLT 3(并假设xsl:strip-space
),可以在xsl:where-populated
的模板中使用parent
:
<xsl:template match="parent">
<xsl:where-populated>
<xsl:next-match/>
</xsl:where-populated>
</xsl:template>
完整的样式表应为
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="childA[grandchildX[text()='03']][grandchildY[text()='02']]"/>
<xsl:template match="parent">
<xsl:where-populated>
<xsl:next-match/>
</xsl:where-populated>
</xsl:template>
</xsl:stylesheet>
在https://xsltfiddle.liberty-development.net/ej9EGdh使用Saxon 9.8 HE的在线示例。
对于XSLT 1,我认为您可以尝试使用空模板
<xsl:template match="parent[childA[grandchildX[. = '03']][grandchildY[. ='02']] and not(*[not(self::childA[grandchildX[. = '03']][grandchildY[. ='02']])])]"/>
即完整的代码将是
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="childA[grandchildX[. = '03']][grandchildY[. ='02']]"/>
<xsl:template match="parent[childA[grandchildX[. = '03']][grandchildY[. ='02']] and not(*[not(self::childA[grandchildX[. = '03']][grandchildY[. ='02']])])]"/>
</xsl:stylesheet>
答案 1 :(得分:2)
首先,我认为您可以简化与此匹配的childA
的当前模板...
<xsl:template match="childA[grandchildX = '03' and grandchildY ='02']"/>
然后,要删除父元素,您需要一个模板来匹配所有符合该条件的所有子元素的parent
元素:
<xsl:template match="parent[count(*) = count(childA[grandchildX = '03' and grandchildY ='02'])]" />
在http://xsltfiddle.liberty-development.net/gWvjQgj/1上查看它的运行情况
这样做的缺点是在两个地方指定了相同的条件。另一种方法是做这样的事情...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent">
<xsl:variable name="children" select="childA[grandchildX = '03' and grandchildY ='02']" />
<xsl:variable name="otherChildren" select="*[count(.|$children) = count($children) + 1]" />
<xsl:if test="$otherChildren">
<xsl:copy>
<xsl:apply-templates select="$otherChildren" />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>