Jump to content

a weird XSLT namespace transformation problem


Recommended Posts

HelloI have quite a strange problem with XSLT transformation, and I have no idea where even to start looking for a solution :In my input file I have something like:

<store  xmlns:food="http://www.food-names">   <element type="food:chocolate">Fazer chocolate</element></store>

Let's say I want to add a items="10" attribute to the "element". In my output file I then have

<store>   <element type="food:chocolate" items="10">Fazer chocolate</element></store>

The "xmlns:food="http://www.food-names"" declaration is missing. Which is quite understandable, because formally this namespace is not referenced in the file at all. But, actually it IS referenced, but from INSIDE the "type" attribute VALUE - but this cannot be noticed by XSLT.. at least this is what I think the reason is.My question is: How to force the XSLT sheet to include ALL namespace declarations that were there in the input file (even the "unused ones")? Or maybe there is some other solution to my problem?Or maybe I understood the reason of my problem incorrectly.. ?(If I add to my input file something like <element food:type="chocolate">Fazer chocolate</item> the namespace IS included correctly. But I am working with already existing files and standards and I cannot adjust them. And without this namespace included, the output file is no longer correct for other tools that use it)My XSLT part responsible for this transformation looks something like that:

<xsl:template match="/*"> <!-- matches root node-->	<xsl:element name="{name(.)}">			         	  <xsl:apply-templates select="node()|@*"/>	      				</xsl:element>    	  </xsl:template><!-- copy all attributes -->	<xsl:template match="@*">		<xsl:copy-of select="."/>	</xsl:template>		<!-- copy all nodes -->	<xsl:template match="*">		<xsl:element name="{name()}" >						<xsl:apply-templates select="node()|@*"/>		</xsl:element>					</xsl:template>

* I tried using xsl:copy like this:
<xsl:template match="*">      <xsl:copy use-attribute-sets="...."/> 	          			          	                  	  				           				</xsl:template>

but this does not copy the node's children.. I also tried xsl:copy-of, but this does not allow inserting new attributes, which I need....

Please help! Any ideas highly appreciated :)

Edited by monami
Link to comment
Share on other sites

The easiest way to solve this is to add the namespace declaration at the top of the stylesheet, like:

<xsl:stylesheet xmlns:food="http://www.food-names" ...>...</xsl:stylesheet>

Namespace declarations that don't point to the XSLT namespace are copied to the output by default.

Link to comment
Share on other sites

With the input being

<store xmlns:food="http://www.food-names"><element type="food:chocolate">Fazer chocolate</element></store>

and the stylesheet being

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">    <xsl:template match="@* | node()">	<xsl:copy>	  <xsl:apply-templates select="@* | node()"/>	</xsl:copy>  </xsl:template>    <xsl:template match="element">	<xsl:copy>	  <xsl:apply-templates select="@*"/>	  <xsl:attribute name="items">10</xsl:attribute>	  <xsl:apply-templates/>	</xsl:copy>  </xsl:template>  </xsl:stylesheet>

the result (tested with Saxon 6.5.5) is

<?xml version="1.0" encoding="utf-8"?><store xmlns:food="http://www.food-names"><element type="food:chocolate" items="10">Fazer chocolate</element></store>

which has both the attribute you want to add and the namespace you want to preserve.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...