[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] preceding-sibling::node() apply template -xsl:copy


Subject: Re: [xsl] preceding-sibling::node() apply template -xsl:copy
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Tue, 17 Apr 2012 08:05:27 +0100

On 17/04/2012 02:49, Senthilukvelaan wrote:
Hi All,
I am using a xslt identity transform and I have one more template to
manipulate "EVENTHEADER" header.
I am not sure ,how to do exclude the  " xmlns:ns2="uri" attribute in
the output using the preceding-sibling::node() apply template.
First, it helps to understand that as far as XSLT is concerned, this thing is not an attribute. In the data model that XSLT sees, an element node has a number of namespace nodes, one for each namespace prefix that is in scope, including the default namespace if any. (Until you understand the data model and the terminology, there is no hope of understanding how namespaces work in XSLT.)

If you have unwanted namespaces in the output, it helps to understand how they got there. First distinguish two cases:

(a) namespace declarations that are unwanted because they are redundant noise: they declare namespace prefixes that are not used. Usually such namespace declarations are harmless, but it's perfectly valid to want them removed. They arise from two sources:

(1) literal result elements in the stylesheet are copied to the result document together with all their in-scope namespaces. To prevent this, use exclude-result-prefixes on the xsl:stylesheet element.

(2) the xsl:copy and xsl:copy-of instructions copy elements from the source document together with all their in-scope namespaces. To prevent this, in XSLT 2.0 use the copy-namespaces="no" attribute; in XSLT 1.0, use xsl:element instead of xsl:copy.

(b) namespace declarations that are unwanted because they cause an element to be in a different namespace from the one intended. Here the key is to understand that the namespace declaration is there because you asked for an element (or occasionally an attribute) to be in a particular namespace, and the namespace declaration is there to honour your request. If you don't want the namespace declaration, don't put the element in that namespace. The namespace that an element goes in depends on how it is created:

(1) for a literal result element, the name of the element in the result tree is the same as its name in the stylesheet

(2) for elements created using xsl:copy[-of], the name of the element in the result tree is the same as its name in the source document

(3) for elements created using xsl:element, the namespace of the element in the result tree is whatever you specify in the namespace attribute.

Note that when I talk here of "the name of an element", I always mean the combination of the namespace and local name.

Simple really.

Michael Kay
Saxonica

<ns2:local xmlns:ns2="uri"><EVENTHEADER>



<xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template>



   <xsl:template match="EVENTHEADER[EVENT_TYPE]">
<xsl:copy>
<xsl:apply-templates select="EVENT_TYPE[position()&lt;
2]/preceding-sibling::node()" />
<  EVENT_TYPES>
<xsl:apply-templates select="EVENT_TYPE[position()&lt; 2]" />
</EVENT_TYPES>
<xsl:apply-templates select="EVENT_TYPE[last()]/following-sibling::node()" />
</xsl:copy>
</xsl:template>


Input: <ns2:local xmlns:ns2="uri"><EVENTHEADER>

Actual output:
<EVENTHEADER  xmlns:ns2="uri">

Expected output:
  <EVENTHEADER>
</EVENTHEADER>

Any pointer would be really helpful.

Thanks
Senthil


Current Thread
Keywords