使用XSL我试图改变这个XML:
<book><title>This is a <b>great</b> book</title></book>
进入这个XML:
<book>This is a <bold>great</bold> book</book>
使用此xsl:
<xsl:for-each select="book/title/*">
<xsl:choose>
<xsl:when test="name() = 'b'">
<bold>
<xsl:value-of select="text()"/>
</bold>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="text()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
但我的输出看起来像这样:
<book><bold>great</bold></bold>
任何人都可以解释为什么<title>
的根文本会丢失吗?我相信我的for-each select语句可能需要修改,但我无法弄清楚应该是什么。
请注意,由于样式表的复杂性,我无法使用<xsl:template match>
。
谢谢!
答案 0 :(得分:7)
这个XPath表达式:
book/title/*
表示“book/title
”的所有子元素。在您的情况下,book/title
有3个子节点:
This is a
<b>...</b>
book
如您所见,其中只有一个是元素,并被选中。如果要获取所有子节点(文本和元素),请使用:
book/title/node()
如果您想单独获取文本节点,请使用:
book/title/text()
答案 1 :(得分:1)
虽然Pavel Minaev提供了这个问题的答案,但必须注意的是,这个问题表明了一个非常糟糕的方法(可能是由于缺乏经验)对XSLT进行处理
这项任务可以以优雅的方式完成,展示了XSLT的强大功能:
在提供的XML文档上应用上述转换时:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="title">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="title/b">
<bold>
<xsl:apply-templates/>
</bold>
</xsl:template>
</xsl:stylesheet>
产生了想要的结果:
<book><title>This is a <b>great</b> book</title></book>
这是一个基本的XSLT设计模式的一个很好的例证 - 覆盖了elment重命名/展平的身份规则。