views:

277

answers:

1

I have an XML file which is in the following format:

<root>
  <category>
    <doctype>
      <name>Doc1</name>
      <site>
        <name>Site1</name>
        <target>iframe</target>
        <url>http://www.gmail.com&lt;/url&gt;
      </site>
    </doctype>
    <doctype>
      <name>Doc2</name>
      <site>
        <name>Site2</name>
        <target>iframe</target>
        <url>http://www.bbc.co.uk&lt;/url&gt;
      </site>
    </doctype>
  </category>
</root>

I need to use it on a standard .net 2.0 TreeView control which requires the XML in the following format

<root>
  <category>  
    <doctype name="Doc1">
      <site name = "Site1" target = "iframe" url = "http://www.gmail.com"&gt;
      </site>
    </doctype>
    <doctype name="Doc2">
      <site name = "Site2" target = "iframe" url = "http://www.bbc.co.uk"&gt;
      </site>
    </doctype>
  </category>
</root>

The biggest complication is the fact that some child nodes of the DOCTYPE node need to be converted to attributes (i.e. NAME) while some stay as child nodes which require attributes of their own (i.e. SITE).

How can this be done using XSLT?

+3  A: 

The following XSLT 1.0 transformation does what you intend.

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

  <xsl:template match="root | category | doctype | site">
    <xsl:copy>
       <xsl:apply-templates select="*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="name | target | url">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Output:

<root>
  <category>
    <doctype name="Doc1">
      <site name="Site1" target="iframe" url="http://www.gmail.com"&gt;&lt;/site&gt;
    </doctype>
    <doctype name="Doc2">
      <site name="Site2" target="iframe" url="http://www.bbc.co.uk"&gt;&lt;/site&gt;
    </doctype>
  </category>
</root>
Tomalak
would apprecaite the simpler solution for the modified question. thanks
eMTeeN