Does XSLT transform XML into a default namespace without adding a prefix?

I am trying to convert an XML file with the following namespace, but could not find a way to make it work with the default namespace without adding a prefix to the output XML.

Original XML file:

<pExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://workflow.converga.com.au/compass"> 

I can make it work by adding a prefix to the default namespace (the last one), but how can I output XML without adding a prefix, is this possible with XslCompiledTransform in .NET 4?

+7
xml xslt
source share
3 answers

I can make it work by adding a prefix for the default namespace (the last one), but how can I output XML without adding a prefix, is this possible with XslCompiledTransform in .NET 4?

Here is a concrete example of how to do this:

This conversion is :

 <xsl:stylesheet version="1.0" xmlns="http://workflow.converga.com.au/compass" xmlns:c="http://workflow.converga.com.au/compass" xmlns:ext="http://exslt.org/common" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="c ext xsl"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="pnewItem"> <item name="wine"> <price>3</price> <quantity>5000</quantity> </item> </xsl:param> <xsl:template match="node()|@*" name="identity"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="c:item[last()]"> <xsl:call-template name="identity"/> <xsl:copy-of select="ext:node-set($pnewItem)/*"/> </xsl:template> </xsl:stylesheet> 

when used with XslCompiledTransform in the following XML document :

 <pExport xmlns="http://workflow.converga.com.au/compass"> <Goods> <item name="tobacco"> <price>5</price> <quantity>1000</quantity> </item> </Goods> </pExport> 

creates the desired (the same XML document with a new addition added), the correct result :

 <pExport xmlns="http://workflow.converga.com.au/compass"> <Goods> <item name="tobacco"> <price>5</price> <quantity>1000</quantity> </item> <item name="wine"> <price>3</price> <quantity>5000</quantity> </item> </Goods> </pExport> 
+4
source share

The key is to use the exclude-result-prefixes attribute in the stylesheet element.

This section has an XSLT FAQ .

+4
source share

You just need to define a default namespace in XSLT. If you also define one with a prefix so that you can easily select elements from the input XML:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://workflow.converga.com.au/compass" xmlns:compass="http://workflow.converga.com.au/compass"> <xsl:template match="compass:pExport"> <pExport>...</pExport> ... 

The above template will match your XML input element - and the generated literal will be in the default namespace (which is the same namespace).

Of course, you should know that in XML the prefix does not matter - two elements are identical if they have the same namespace and local name, even if both prefixes are defined for this namespace.

 <element xmlns="http://test.com"></element> <ns01:element xmlns:ns01="http://test.com"></ns01:element> 

The two elements above are the same because they have the same full name.

+1
source share

All Articles