开发者

XSLT transform XML with default namespace without adding prefix?

I am trying to transform an XML file with the following namespace, but couldn't find out a way to make it working 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 working by adding a prefix to the default namespace (the last one), but how could I output a XML without adding a prefix, i开发者_JAVA技巧t is possible by using XslCompiledTransform in .NET 4 ?


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

Here is a concrete example how to do it:

This transformation:

<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 applied with XslCompiledTransform on 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>

produces the wanted (the same XML document with a new item added), 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>


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

There are some good explanations in this section of the XSLT FAQ.


You simply need to define your default namespace in the XSLT. If you also define one with a prefix as well so you can select items from the input XML with ease:

<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 against your input XML element - and the literal element created will be in the default output namespace (which is the same namespace).

Of course you should be aware that in XML the prefix is irrelevant - two items are identical if they have the same namespace and local name, even if the two prefixes are defined for that one 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 fully qualified name.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜