[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Namespace issue when running a Xalan transform th

Subject: Re: Namespace issue when running a Xalan transform through Java
From: Martin Honnen <Martin.Honnen@xxxxxx>
Date: Fri, 27 Aug 2010 19:36:41 +0200
Re:  Namespace issue when running a Xalan transform  th
Etheridge, Stephen wrote:

The extra namespace declarations all appear in elements that are in a
different namespace in the source, but which need to end up in the
namespace www.logica.com/project and are transformed by the following
extract of a stylesheet:

<xsl:template match="*" mode="copy">
			<xsl:variable name="element-name"
select="local-name()"></xsl:variable>
			<xsl:choose>
				<xsl:when test="contains($element-name,
'List')">
					<xsl:call-template
name="process-lists"></xsl:call-template>
				</xsl:when>
				<xsl:otherwise>
					<xsl:element
name="{local-name()}" namespace="http://www.logica.com/project">
					<xsl:apply-templates
mode="copy"></xsl:apply-templates>
					</xsl:element>
				</xsl:otherwise>
			</xsl:choose>
	
</xsl:template>

	
<xsl:template name="process-lists">	
	<xsl:variable name="element-name"
select="local-name()"></xsl:variable>	
	<xsl:element name="{$element-name}"
namespace="http://www.logica.com/pnd"><xsl:value-of
select="./dip:N"/></xsl:element>	
	<xsl:variable name="local-element-val"><xsl:value-of
select="$element-name"/><xsl:text>LocalVal</xsl:text></xsl:variable>	
	<xsl:element name="{$local-element-val}"
namespace="http://www.logica.com/project"><xsl:value-of
select="./dip:NP"/></xsl:element>		
</xsl:template>

The namespace addition to the <xsl:element> processing is not reproduced
by XSLTProc or Xalan via the command line, only in the default javax
implementation.

I tried to morph that snippet into a test case, input sample is


<root xmlns="http://example.com/dip">
  <foo><bar>baz</bar></foo>
  <ListExample>
    <N>N1</N>
    <NP>NP1</NP>
  </ListExample>
  <ListExample>
    <N>N2</N>
    <NP>NP2</NP>
  </ListExample>
  <ListExample>
    <N>N3</N>
    <NP>NP3</NP>
  </ListExample>
</root>

stylesheet is

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dip="http://example.com/dip"
  xmlns="http://www.logica.com/project"
  version="1.0">

  <xsl:template match="/">
    <xsl:apply-templates mode="copy"/>
  </xsl:template>

<xsl:template match="*" mode="copy">
			<xsl:variable name="element-name"
select="local-name()"></xsl:variable>
			<xsl:choose>
				<xsl:when test="contains($element-name,
'List')">
					<xsl:call-template
name="process-lists"></xsl:call-template>
				</xsl:when>
				<xsl:otherwise>
					<xsl:element
name="{local-name()}" >
					<xsl:apply-templates
mode="copy"></xsl:apply-templates>
					</xsl:element>
				</xsl:otherwise>
			</xsl:choose>
	
</xsl:template>

	
<xsl:template name="process-lists">	
	<xsl:variable name="element-name"
select="local-name()"></xsl:variable>	
	<xsl:element name="{$element-name}"
namespace="http://www.logica.com/pnd"><xsl:value-of
select="./dip:N"/></xsl:element>	
	<xsl:variable name="local-element-val"><xsl:value-of
select="$element-name"/><xsl:text>LocalVal</xsl:text></xsl:variable>	
	<xsl:element name="{$local-element-val}"><xsl:value-of
select="./dip:NP"/></xsl:element>		
</xsl:template>

</xsl:stylesheet>

and indeed the output with the Sun/Oracle Java JRE 1.6 transformer is both wrong and odd, I get

<?xml version="1.0" encoding="UTF-8"?><root>
<foo><bar>baz</bar></foo>
<ns0:ListExample xmlns:ns0="http://www.logica.com/pnd">N1</ns0:ListExample><ListExampleLocalVal>NP1</ListExampleLocalVal>
<ns1:ListExample xmlns:ns1="http://www.logica.com/pnd">N2</ns1:ListExample><ListExampleLocalVal>NP2</ListExampleLocalVal>
<ns2:ListExample xmlns:ns2="http://www.logica.com/pnd">N3</ns2:ListExample><ListExampleLocalVal>NP3</ListExampleLocalVal>
</root>


while Saxon 6.5.5 outputs

<?xml version="1.0" encoding="utf-8"?><root xmlns="http://www.logica.com/project">
<foo><bar>baz</bar></foo>
<ListExample xmlns="http://www.logica.com/pnd">N1</ListExample><ListExampleLocalVal>NP1</ListExampleLocalVal>
<ListExample xmlns="http://www.logica.com/pnd">N2</ListExample><ListExampleLocalVal>NP2</ListExampleLocalVal>
<ListExample xmlns="http://www.logica.com/pnd">N3</ListExample><ListExampleLocalVal>NP3</ListExampleLocalVal>
</root>


So the Sun/Oracle transformer drops one namespace (which is a bug) and generates a new prefix for the each element in the other namespace (which is awful but probably not a bug considering that the XSLT 1.0 specification does not outline serialization).


I am not sure what to suggest, it looks as if Michael Dykman was completely right. With Java you have two alternative XSLT 1.0 processors with Xalan and with Saxon 6.5.5 and you can even move to Saxon 9 and XSLT 2.0 easily. That seems to be the right approach.


I even tried to avoid the prefix ns[n] clutter with the Sun/Oracle transformer by suggesting a prefix in the stylesheet with e.g.

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dip="http://example.com/dip"
  xmlns="http://www.logica.com/project"
  xmlns:pnd="http://www.logica.com/pnd"
  version="1.0">

  <xsl:template match="/">
    <xsl:apply-templates mode="copy"/>
  </xsl:template>

<xsl:template match="*" mode="copy">
			<xsl:variable name="element-name"
select="local-name()"></xsl:variable>
			<xsl:choose>
				<xsl:when test="contains($element-name,
'List')">
					<xsl:call-template
name="process-lists"></xsl:call-template>
				</xsl:when>
				<xsl:otherwise>
					<xsl:element
name="{local-name()}" >
					<xsl:apply-templates
mode="copy"></xsl:apply-templates>
					</xsl:element>
				</xsl:otherwise>
			</xsl:choose>
	
</xsl:template>

	
<xsl:template name="process-lists">	
	<xsl:variable name="element-name"
select="local-name()"></xsl:variable>	
	<xsl:element name="pnd:{$element-name}"><xsl:value-of
select="./dip:N"/></xsl:element>	
	<xsl:variable name="local-element-val"><xsl:value-of
select="$element-name"/><xsl:text>LocalVal</xsl:text></xsl:variable>	
	<xsl:element name="{$local-element-val}"><xsl:value-of
select="./dip:NP"/></xsl:element>		
</xsl:template>

</xsl:stylesheet>

then for instance Saxon honours that and outputs

<?xml version="1.0" encoding="utf-8"?><root xmlns="http://www.logica.com/project">
<foo><bar>baz</bar></foo>
<pnd:ListExample xmlns:pnd="http://www.logica.com/pnd">N1</pnd:ListExample><ListExampleLocalVal>NP1</ListExampleLocalVal>
<pnd:ListExample xmlns:pnd="http://www.logica.com/pnd">N2</pnd:ListExample><ListExampleLocalVal>NP2</ListExampleLocalVal>
<pnd:ListExample xmlns:pnd="http://www.logica.com/pnd">N3</pnd:ListExample><ListExampleLocalVal>NP3</ListExampleLocalVal>
</root>


but the Sun/Oracle transformer then throws an error "The namespace for prefix pnd was not declared" which seems another bug.

--

	Martin Honnen
	http://msmvps.com/blogs/martin_honnen/

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.