tags:

views:

33

answers:

2

Hello all,

I would like to remove all elements from XML except content of element called <source>. E.g.:

<root>
 <a>This will be stripped off</a>
 <source>But this not</source>
</root>

After XSLT:

But this not

I have tried this but with no luck (no output):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

 <xsl:output omit-xml-declaration="yes"/>

    <xsl:template match="source">
      <xsl:copy>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">

</xsl:stylesheet>

From comments:

In my real XML I have the source element in different namespace. I need to google how to create a match pattern for element in different namespace. I would like to put each extracted string also to newline ;-)

+1  A: 

You're not far off. The reason you're not getting any output is because your root match-all template isn't recursing but just terminating so you need to put an apply-templates call inside it. The following stylesheet gives the expected output.

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

    <xsl:output method="text"/>

    <xsl:template match="@*|node()">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>

    <xsl:template match="source">
        <xsl:value-of select="text()"/>
    </xsl:template>

</xsl:stylesheet>

Note that I've changed the output mode to text and the source template to simply output the textual value of the node, because it looks like you want text and not XML output.

Greg Beech
I see. But its still does not work. No output.
lzap
I forgot to remark that my source elements are not in the root. They are deep (like on 5th level or something). I have tried match="//source" but with no luck :-(
lzap
I'm not sure what you mean by "no output"? I tested it using the Visual Studio XSLT editor and it definitely produces the output "But this not" when given the source document.
Greg Beech
The `<source>` elements don't need to be at the root with this stylesheet; it will traverse the entire XML structure until it finds them.
Greg Beech
You are right. It works with the example above. In my real XML I have the source element in different namespace. I need to google how to create a match pattern for element in different namespace. THANK YOU.
lzap
Got it! Thanks a lot!
lzap
I would like to put each extracted string also to newline ;-)
lzap
I have used xsl:text with a space :-D
lzap
Glad to be of help :)
Greg Beech
@lzap - in order to select any `source` element, regardless of the namespace, you could use this: `match="*[local-name()='source']"`
Mads Hansen
A: 

Just for fun, the sortest solution:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ex="http://example.org"&gt;
    <xsl:output method="text"/>
    <xsl:template match="text()"/>
    <xsl:template match="ex:source">
        <xsl:value-of select="concat(.,'&#xA;')"/>
    </xsl:template>
</xsl:stylesheet>

With this input:

<root xmlns="http://example.org"&gt;
    <a>This will be stripped off</a>
    <source>But this not</source>
</root>

Output:

But this not
Alejandro