Reputation: 10012
I have a simple XML file with simple XSLT transform and XslCompiledTransform does a good job when I don't have any xmlns in my XML file, but when I do the resulting XML file is empty - why?
Here is my code:
public static void XmlToXmlWithXsl(string xmlFilePath, string xmlOutputFilePath, string xslFilePath)
{
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xslFilePath);
// Create the writer.
XmlWriterSettings settings = xslt.OutputSettings;
XmlWriter writer = XmlWriter.Create(xmlOutputFilePath, settings);
// Execute the transformation.
xslt.Transform(xmlFilePath, writer);
writer.Close();
}
Here is my XML (version with xmlns):
<?xml version="1.0" encoding="utf-8"?>
<messages xmlns="blah">
<message>
<id>blah</id>
<text>Polski</text>
<text lang="en">English</text>
<notes />
</message>
<message>
<id>blah2</id>
<text lang="pl">Polski</text>
<text lang="en">English</text>
<notes />
</message>
</messages>
Here is my XSL (little smaller then it was):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns="blablabla"
>
<xsl:output method="xml" indent="yes" />
<xsl:variable name="empty_string"></xsl:variable>
<!-- root -->
<xsl:template match="/">
<xsl:element name="messages">
<xsl:apply-templates select="//message" />
</xsl:element>
</xsl:template>
<!-- AS-IS with xml content -->
<xsl:template match="message">
<xsl:element name="{name(.)}"><xsl:apply-templates /></xsl:element>
</xsl:template>
<!-- AS-IS with text content -->
<xsl:template match="id|notes|text">
<xsl:element name="{name(.)}"><xsl:value-of select="." /></xsl:element>
</xsl:template>
</xsl:stylesheet>
The output is:
<?xml version="1.0" encoding="utf-8"?>
<messages xmlns="blablabla" />
The output should be:
<?xml version="1.0" encoding="utf-8"?>
<messages xmlns="blablabla">
<message>
<id>blah</id>
<text>Polski</text>
<text>English</text>
<notes></notes>
</message>
<message>
<id>blah2</id>
<text>Polski</text>
<text>English</text>
<notes></notes>
</message>
</messages>
Upvotes: 1
Views: 3597
Reputation: 167571
This is the XSLT/XPath 1.0 FAQ: to select or match elements in a certain namespace, even the default namespace, with XSLT/XPath 1.0 you need to bind a prefix to the namespace URI and use that prefix in path expressions or match patterns to qualify element names:
<xsl:stylesheet version="1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:df="blablabla"
>
<xsl:output method="xml" indent="yes" />
<xsl:variable name="empty_string"></xsl:variable>
<!-- root -->
<xsl:template match="/">
<xsl:element name="messages">
<xsl:apply-templates select="//df:message" />
</xsl:element>
</xsl:template>
<!-- AS-IS with xml content -->
<xsl:template match="df:message">
<xsl:element name="{name(.)}"><xsl:apply-templates /></xsl:element>
</xsl:template>
<!-- AS-IS with text content -->
<xsl:template match="df:id|df:notes|df:text">
<xsl:element name="{name(.)}"><xsl:value-of select="." /></xsl:element>
</xsl:template>
Upvotes: 3