Question

Suppose I have an Xml like this:

<?xml version="1.0" encoding="utf-8"?>
 <xsl:output method="xml"  indent="yes" omit-xml-declaration="yes"/>
<root xmlns:dbk="http://K.com"
    xmlns:dbs="http://S.com"
    xmlns:dbp="http://p.com"
    xmlns:dbm="http://z.com" >
   <a>
       This is the first text
       <alter>
             <dbk:x> Hello </dbk:x>
             <dbs:y role='Strong'>World </dbs:y>
      </alter>
  </a>
  <d>
      This is the second text
      <alter>
            <dbp:w> How are </dbp:w>
            <dbm:z role='Italic'>  you? </dbm:z>
      </alter>
  </d>
</root>

I want to capture all alter elements however everything should be printed out including opening and closing tags as well as attributes so the output should be like this:

<x> Hello </x>
<y role='Strong'>  World </y> 
<w> How are </w>
<z role='Italic'>  you? </z> 

Note that

  1. I want to output all tags ( both opening and closing tags and attributes) within the alter element as well as the text
  2. The tags can be varied and the decision should NOT be based on the name of the tag as they are all auto-generated and dynamic
  3. The tag name within one alter element can be different from the tags added to another alter element like above :

The first alter has

<x></x>

and

<y role=''></y> 

while the second alter has

  <w></w> 

and

  <z role=''><z>

And the third alter can have something else and ….

Not sure what the XSLT should look like?

Edited:

Based on @Mads Hansen’s solution , the output would be :

<dbk:x xmlns:dbk="http://K.com" xmlns:dbs="http://S.com" xmlns:dbp="http://p.com"     xmlns:dbm="http://z.com"> Hello </dbk:x>
<dbs:y role="Strong" xmlns:dbs="http://S.com" xmlns:dbk="http://K.com" xmlns:dbp="http://p.com" xmlns:dbm="http://z.com">World </dbs:y>
<dbp:w xmlns:dbp="http://p.com" xmlns:dbk="http://K.com" xmlns:dbs="http://S.com" xmlns:dbm="http://z.com"> How are </dbp:w>
<dbm:z role="Italic" xmlns:dbm="http://z.com" xmlns:dbk="http://K.com" xmlns:dbs="http://S.com" xmlns:dbp="http://p.com">  you? </dbm:z>

The problem is that all namespaces have been added to outport as well which is not desired.

Is there any way to get rid of all namespaces?

Was it helpful?

Solution

The following stylesheet:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <output>
        <xsl:apply-templates select="descendant::alter/*"/>
    </output>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:copy/> 
</xsl:template>

</xsl:stylesheet>

when applied to your example input, will produce this result:

<output>
   <x> Hello </x>
   <y role="Strong">World </y>
   <w> How are </w>
   <z role="Italic">  you? </z>
</output>

Removing the <output> tags from the first template will result in invalid XML, which some processors (e.g. libxslt) may render as:

<x> Hello </x><y role="Strong">World </y><w> How are </w><z role="Italic">  you? </z>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top