开发者

NamesSpace removal from XSLT

Hi I am writing an XSLT and within that I am using <xsl:copy-of> function. Now when it's executed then namesapce from xml are also getting copied. In order to remove that I used function like <xsl:copy-of select="$RootNode/Child" copy-namespaces="no"/>. But If Child is having some more child elements then namespaces are appearing in that. So can anyone please tell me how can I remove that. Below is the snippet of my xslt and XML I am using.

<xsl:template match="/">
    <xsl:element name="Parent">
    <xsl:copy-of select="Child" copy-namespaces="no"/>
    </xsl:element>

And XML is:

<Child>
<GrandChild>
 <PhoneNumberType>DayPhone</PhoneNumberType>
</GrandChild></Child>

namespaces are not appearing in CustomerParty but t开发者_如何学Chey are present in Child but they are present in GrandChild.


The copy-namespaces="no" attribute doesn't strip off all namespace nodes -- as noted in the XSLT 2.0 spec:

If it takes the value no, then none of the namespace nodes are copied: however, namespace nodes will still be created in the result tree as required by the namespace fixup process: see 5.7.3 Namespace Fixup. This attribute affects all elements copied by this instruction: both elements selected directly by the select expression, and elements that are descendants of nodes selected by the select expression.

Here is an example how to get rid of all the (non-mandatory) namespace nodes:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="*">
     <xsl:element name="{local-name()}">
       <xsl:apply-templates select="node()|@*"/>
     </xsl:element>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:attribute name="{local-name()}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

When this general transformation is applied on this XML document:

<x:nums xmlns:x="my:x">
  <x:num>01</x:num>
  <x:num>02</x:num>
  <x:num>03</x:num>
  <x:num>04</x:num>
  <x:num>05</x:num>
  <x:num>06</x:num>
  <x:num>07</x:num>
  <x:num>08</x:num>
  <x:num>09</x:num>
  <x:num>10</x:num>
</x:nums>

the wanted, correct result is produced:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

Do note:

  1. The transformation is not XSLT-2.0 - specific and can be used with XSLT 1.0, too.

  2. Removing all namespace nodes is generally an unsafe process, because nodes from different namespaces are all put in the "no namespace". In this process some attributes may be lost and the process is generally not reversible (not 1:1).


With this template you should be able to remove namespaces:

    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

Also refer to: http://www.devang-gandhi.net/blog/remove-namespace-attribute-from-xml-root-xslt/

Does this help you with your problem?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜