tags:

views:

47

answers:

3

I currently have a xml file like this:

<aaa>
    <b>I am a <i>boy</i></b>.
</aaa>

How can I get the exact string as: <b>I am a <i>boy</i></b>.? Thanks.

+1  A: 

You have to tell XSLT that you want to copy elements through as well. That can be done with an additional rule. Note that I use custom select clauses on my apply-templates elements to select attributes as well as all node-type objects. Also note that the rule for aaa takes precedence, and does not copy the aaa element itself to the output.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:template match="aaa">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:template>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Owen S.
+2  A: 
<aaa> 
    <b>I am a <i>boy</i></b>. 
</aaa> 

How can I get the exact string as: <b>I am a <i>boy</i></b>.?

The easiest/shortest way to do this in your case is to output the result of the following XPath expression:

/*/node()

This means: "Select all nodes that are children of the top element."

Of course, there are some white-space-only text nodes that we don't want selected, but XSLT can take care of this, so the XPath expression is just as simple as shown above.

Now, to get the result with an XSLT transformation, we use the following:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
   <xsl:copy-of select="/*/node()"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document, the wanted result is produced:

<b>I am a <i>boy</i></b>.

Do note:

  1. The use of the <xsl:copy-of> xslt instruction (not <xsl:value-of>), which copies nodes, not string values.

  2. The use of the <xsl:strip-space elements="*"/> XSLT instruction, directing the XSLT processor to ignore any white-space-only text node in the XML document.

Dimitre Novatchev
Which goes to show: XSLT can do anything XPath can do. :-) Note that you lose recursive tweakability with this approach.
Owen S.
@Dimitre - It's missing the ".". The xpath should be something like: `<xsl:copy-of select="/*/node()[not(normalize-space()='')]"/>`, which will serialize to output that is not well-formed, but is the string that was asked for.
Mads Hansen
@Mads-Hansen: Thanks, I hadn't noticed the "." -- thought it was a punctuation mark ending the sentence in the question.I updated my answer accordingly.
Dimitre Novatchev
Thanks everyone...
Wilson
A: 

Thanks everyone. I will give it a try. Cheers.

Wilson