英文:
Remove element with XSLT where CDATA value is empty
问题
我对XSLT相当陌生,发现很难正确理解它...
我想要实现的是,将XML中每个CDATA没有值的<text>元素删除。
我的XML如下:
<description>
<internet>
<texts_short>
<text locale="de"><![CDATA[]]></text>
<text locale="en"><![CDATA[EXF/RETAIL]]></text>
</texts_short>
<texts_long>
<text locale="de"><![CDATA[]]></text>
</texts_long>
</internet>
<vehicle>
<texts_short/>
<texts_long>
<text locale="en"><![CDATA[Backend Functions Bundle]]></text>
</texts_long>
<texts_text2speech>
<text locale="de"><![CDATA[]]></text>
</texts_text2speech>
</vehicle>
</description>
我已经准备好了以下的XSLT,它会删除没有条件的每个text元素:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text"/>
</xsl:stylesheet>
要实现只删除CDATA值为空的<text>元素,可以修改XSLT如下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text">
<xsl:if test="string-length(normalize-space(.//text())) > 0">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这个XSLT将只保留具有非空CDATA值的<text>元素,其他的将被删除。
英文:
I am quite new to XSLT and find it very hard to understand properly..
I want to achieve that every <text> element where my CDATA has no value should be removed from the XML.
My XML looks like this:
<description>
<internet>
<texts_short>
<text locale="de"><![CDATA[]]></text>
<text locale="en"><![CDATA[EXF/RETAIL]]></text>
<texts_long>
<text locale="de"><![CDATA[]]></text>
</texts_long>
</internet>
<vehicle>
<texts_short/>
<texts_long>
<text locale="en"><![CDATA[Backend Functions Bundle]]></text>
</texts_long>
<texts_text2speech>
<text locale="de"><![CDATA[]]></text>
</texts_text2speech>
</vehicle>
</description>
I have already prepared the following XSLT which removes every text element with no condition:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text"/>
</xsl:stylesheet>
How can I achieve that only the <text> elements with empty CDATA value will be removed - so that only the one with text "EXF/RETAIL" and "Backend Functions Bundle" will stay?
Thank you in advance!
答案1
得分: 1
你可以使用<xsl:template match="text[not(normalize-space())]"/>
,但这将移除没有内容、空的CDATA部分、只包含空格的CDATA部分等的text
元素。在XSLT中无法知道元素的内容是由CDATA部分还是普通文本节点在词法标记中提供的。
英文:
What you can do is use <xsl:template match="text[not(normalize-space())]"/>
but that will remove text
elements having no content, an empty CDATA section, a CDATA section with only white space etc. There is no way in XSLT to know whether the element's content was provided in the lexical markup by a CDATA section or an ordinary text node.
答案2
得分: 0
翻译后的代码部分如下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" cdata-section-elements="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text[not(normalize-space())]"/>
</xsl:stylesheet>
英文:
It looks like adding cdata-section-elements="text" to the output together with Martin Honnen's answer solved my problem:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" cdata-section-elements="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text[not(normalize-space())]"/>
</xsl:stylesheet>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论