如果子节点为空,则移除父节点
Remove parent node if child node is empty
我正在尝试使用 xslt 转换给定的 XML。需要注意的是,如果给定的子节点不存在,我将不得不删除父节点。我确实做了一些模板匹配,但我被卡住了。任何帮助将不胜感激。
输入xml:
<?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>
预期输出:
<?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>
问题是如果我使用模板匹配,例如
<xsl:template match="item[not(value)]"/>
如 deleting the parent node if child node is not present in xml using xslt 中所述,然后它会完全删除所有内容,因为 main/item/value 也是空的。
我需要的是如果元素为空则移除但仅当元素没有子元素时才移除。
我认为您想删除它根本没有子元素的元素(无论这些子元素是元素还是文本节点)。尝试插入此模板:
<xsl:template match="item">
<xsl:if test="exists(value/node())">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
您应该首先从 XSLT 标识模板开始
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
那么,您所需要的只是一个匹配 item
元素的模板,其中所有后代叶 value
元素都是空的。
<xsl:template match="item[not(descendant::value[not(*)][normalize-space()])]" />
因此,模板匹配它,但不输出它。
试试这个 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>
如果我没看错的话,你想做的是:
XSLT 1.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>
这将删除所有 item
没有 value
子级的 一些 内容。
我正在尝试使用 xslt 转换给定的 XML。需要注意的是,如果给定的子节点不存在,我将不得不删除父节点。我确实做了一些模板匹配,但我被卡住了。任何帮助将不胜感激。
输入xml:
<?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>
预期输出:
<?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>
问题是如果我使用模板匹配,例如
<xsl:template match="item[not(value)]"/>
如 deleting the parent node if child node is not present in xml using xslt 中所述,然后它会完全删除所有内容,因为 main/item/value 也是空的。
我需要的是如果元素为空则移除但仅当元素没有子元素时才移除。
我认为您想删除它根本没有子元素的元素(无论这些子元素是元素还是文本节点)。尝试插入此模板:
<xsl:template match="item">
<xsl:if test="exists(value/node())">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
您应该首先从 XSLT 标识模板开始
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
那么,您所需要的只是一个匹配 item
元素的模板,其中所有后代叶 value
元素都是空的。
<xsl:template match="item[not(descendant::value[not(*)][normalize-space()])]" />
因此,模板匹配它,但不输出它。
试试这个 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>
如果我没看错的话,你想做的是:
XSLT 1.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>
这将删除所有 item
没有 value
子级的 一些 内容。