我有以下 XSL 工作,但应该有一种方法可以在不使用 xsl:for-each 元素的情况下重写它。我需要获取任意 XML block ,删除所有具有“drop”属性的元素,并将剩余文本与空格连接起来,而不在连接文本的末尾或末尾添加额外的空格。
我应该说,我唯一可以关闭的 XML 部分是“drop”属性。我无法删除任何元素名称,例如“testing”、“catalog”、“book”等。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:for-each select="//*[not(@drop)]/text()">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我一直在测试的 XML:
<testing>
<text drop="meta">Drop this meta</text>
<catalog>
<book id="bk101">
<text drop="stuff">Drop this stuff</text>
<title ti="Full Title">XML Developer\ts Guide</title>
<author>Gambardella, Matthew</author>
</book>
</catalog>
</testing>
和有效输出:
XML Developer s Guide Gambardella, Matthew
编辑:正如 @michael.hor257k 所指出的,它假设 XML 不会有任何 mixed content
最佳答案
正如 Martin Honnen 在他删除的答案中指出的那样,在 XSLT 2.0 中,这可以通过单个 xsl:value-of
指令来完成。这是他的答案,我稍加修正:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:value-of select="//*[not(@drop) and text()]" separator=" "/>
</xsl:template>
</xsl:stylesheet>
但是,这假设源 XML 中没有混合内容(我相信其他答案也是如此)。如果这是一个要求,您可以使用:
<xsl:value-of select="string-join(//*[not(@drop)]/text(), ' ')" />
相反。
关于xslt - 重写而不使用 <xsl :for-each>; select all text separated by spaces; dropping text with attribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37034822/