Xslt 如果子节点为空,则删除父节点
我正在尝试使用xslt转换给定的XML。需要注意的是,如果给定的子节点不存在,我将不得不删除父节点。我确实做了一些模板匹配,但我被卡住了。任何帮助都将不胜感激 输入xml:Xslt 如果子节点为空,则删除父节点,xslt,xslt-2.0,Xslt,Xslt 2.0,我正在尝试使用xslt转换给定的XML。需要注意的是,如果给定的子节点不存在,我将不得不删除父节点。我确实做了一些模板匹配,但我被卡住了。任何帮助都将不胜感激 输入xml: <?xml version="1.0" encoding="UTF-8"?> <main> <item> <value> <item> <value>ABC</value&
<?xml version="1.0" encoding="UTF-8"?>
<main>
<item>
<value>
<item>
<value>ABC</value>
<key>test1</key>
</item>
<item>
<value>XYZ</value>
<key>test2</key>
</item>
<item>
<value></value>
<key>test3</key>
</item>
</value>
</item>
<item>
<value />
<key>test4</key>
</item>
<item>
<value>PQR</value>
<key>test5</key>
</item>
</main>
基础知识
测试1
XYZ
测试2
测试3
测试4
PQR
测试5
预期产出:
<?xml version="1.0" encoding="UTF-8"?>
<main>
<item>
<value>
<item>
<value>ABC</value>
<key>test1</key>
</item>
<item>
<value>XYZ</value>
<key>test2</key>
</item>
</value>
</item>
<item>
<value>PQR</value>
<key>test5</key>
</item>
</main>
基础知识
测试1
XYZ
测试2
PQR
测试5
问题是如果我使用模板匹配,例如
如中所述,然后它会完全删除所有内容,因为main/item/value也是空的
我需要的是在元素为空时删除,但仅当元素没有子元素时才删除。我认为您希望删除元素中没有子元素的元素(无论这些子元素是元素还是文本节点)。尝试插入此模板:
您应该首先从XSLT标识模板开始
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
因此,模板匹配它,但不输出它
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="item[not(descendant::value[not(*)][normalize-space()])]" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果我没有看错,您需要执行以下操作: XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item[not(value[node()])]"/>
</xsl:stylesheet>
这将删除没有包含某些内容的
值的项。此外,如果键test1和test2的值为空,则顶级项元素也应从输出中排除。我尝试过它不起作用,并给出xslt编译错误。错误:XSLTProcessor::transformToXml():XmlXPathCompiledVal:1堆栈上剩余的对象。@Ady211您确定您使用的是XSLT 2.0,正如您问题上的标记所示吗?我使用的是XSLT 1.0。这很有效。这个xslt如何区分main/item/value(它是空的并且有子节点item)和item/value?是不是(*)在耍把戏?是的。执行not(*)
检查是否缺少子元素,因此它将只匹配“叶”元素。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item[not(value[node()])]"/>
</xsl:stylesheet>