markf78
markf78

Reputation: 627

How to get XslCompiledTransform to include xmlns in root element?

I'm trying to use XslCompiledTransform C# class to transform one xml file into another. However, the xmlns attribute is not being transferred.

My code:

XmlReader reader = XmlReader.Create("machine1.xml");
XmlWriter writer = XmlWriter.Create("machine2.xml");

XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("transform.xsl");

transform.Transform(reader, writer);

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns="http://schemas.datacontract.org/2004/07/CMachines" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <!-- Copy everything not subject to the exceptions below -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <!-- Ignore the disabled element -->
  <xsl:template match="Disabled" />
</xsl:stylesheet>

Input:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMachine xmlns="http://schemas.datacontract.org/2004/07/CMachines" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Machine>
      <Name>DellM7600</Name>
      <ID>1</ID>
      <Type>Laptop</Type>
      <Disabled>false</Disabled>
      <SerialNum>47280420</SerialNum>
    </Machine>
    <Machine>
      <Name>DellD600</Name>
      <ID>2</ID>
      <Type>Laptop</Type>
      <Disabled>false</Disabled>
      <SerialNum>53338123</SerialNum>
    </Machine>
    </ArrayOfMachine>

This is the actual Output:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMachine xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/CMachines" >
    <Machine>
      <Name>DellM7600</Name>
      <ID>1</ID>
      <Type>Laptop</Type>
      <Disabled>false</Disabled>
      <SerialNum>47280420</SerialNum>
    </Machine>
    <Machine>
      <Name>DellD600</Name>
      <ID>2</ID>
      <Type>Laptop</Type>
      <Disabled>false</Disabled>
      <SerialNum>53338123</SerialNum>
    </Machine>
    </ArrayOfMachine>

This is the desired output:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMachine xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/CMachines" >
    <Machine>
      <Name>DellM7600</Name>
      <ID>1</ID>
      <Type>Laptop</Type>
      <SerialNum>47280420</SerialNum>
    </Machine>
    <Machine>
      <Name>DellD600</Name>
      <ID>2</ID>
      <Type>Laptop</Type>
      <SerialNum>53338123</SerialNum>
    </Machine>
    </ArrayOfMachine>

Upvotes: 1

Views: 717

Answers (1)

Tim C
Tim C

Reputation: 70618

You were previously try to use xpath-default-namespace in your XSLT, which is not supported in XSLT 1.0.

Instead, you will need to use namespace prefix, bound to the namespace specified in your XML, to match the Disabled element which is in that namespace.

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:cm="http://schemas.datacontract.org/2004/07/CMachines" 
                              xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <!-- Copy everything not subject to the exceptions below -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <!-- Ignore the disabled element -->
  <xsl:template match="cm:Disabled" />
</xsl:stylesheet>

Note the namespace prefix used is arbitrary, as long as the namespace URI matches.

Upvotes: 2

Related Questions