problem using the xsl method for-each
Using XSL I am trying to turn this XML:
<book><title>This is a <b>great</b> book</title></book>
into this XML:
<book>This is a <bold>great</bold> book</book>
using this 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>
but my output is looking like this:
<book><bold>great</bold></bold>
Can anyone explain why the root text of <title>
is getting lost? I believe my for-each select statem开发者_StackOverflowent may need to be modified but I can't figure out what is should be.
Keep in mind that I cannot use an <xsl:template match>
because of the complexity of my style sheet.
Thanks!
This XPath expression:
book/title/*
means "all child elements of book/title
". In your case, book/title
has 3 child nodes:
- Text node:
This is a
- Element node:
<b>...</b>
- Text node:
book
As you can see, only one of them is an element, and gets selected. If you want to get all child nodes, both text and elements, use this:
book/title/node()
If you want to get text nodes separately, use this:
book/title/text()
While Pavel Minaev provided the answer to the question, it must be noted that this question demonstrates a really bad approach (probably due to lack of experience) to XSLT procesing.
The task can be accomplished in an elegant way, which demonstrates the power of XSLT:
When the above transformation is applied on the provided XML document:
<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>
the wanted result is produced:
<book><title>This is a <b>great</b> book</title></book>
This is a good illustration of one of the basic XSLT design patterns -- overriding the identity rule for elment renaming/flattening.
精彩评论