开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜