Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old July 26th, 2007, 08:47 AM
Registered User
 
Join Date: Jul 2007
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default Namespace trouble when nesting xslt-s

[u]General description:</u>
I have two xslt-transformations that are almost indentical except for the namespaces. I want to share as much as possible by using the include statement but I ran into problem with the namespaces.

[u]Details:</u>
I have two messages to only differ in namespace.

Message 1: -- message1.xml --
Code:
<?xml version="1.0" encoding="utf-8" ?>
<message sender="me" receiver="you" xmlns="http://mycompany/messages/2.0">
    <header title="some title"/>
    <body parts="2"/>
</message>
Message 2: -- message2.xml --
Code:
<?xml version="1.0" encoding="utf-8" ?>
<message sender="me" receiver="you" xmlns="http://mycompany/messaging/3.0">
    <header title="some title"/>
    <body parts="2"/>
</message>
I have a simple xslt-transformation for these messages that also only differs in namespace.

Transformation for Message1 is: -- simpletransformation.xslt --
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://mycompany/messages/2.0" xmlns:ms="http://mycompany/messages/2.0">
    <xsl:import href="attributes.xslt"/>
    <xsl:output method="xml" />

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

    <xsl:template match="/ms:message">
        <xsl:variable name="parts"><xsl:call-template name="GetBodyParts" /></xsl:variable>        
        <xsl:element name="note">
            <xsl:choose>
                <xsl:when test="$parts='1'">Short message</xsl:when>
                <xsl:otherwise>Long message</xsl:otherwise>
            </xsl:choose>
            from <xsl:value-of select="@sender"/>
        </xsl:element>
    </xsl:template>    
</xsl:stylesheet>
Transformation for Message2 is: -- simpletransformation2.xslt --
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://mycompany/messaging/3.0"
xmlns:ms="http://mycompany/messaging/3.0">
    <xsl:import href="attributes.xslt"/>
    <xsl:output method="xml" />

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

    <xsl:template match="/ms:message">
        <xsl:variable name="parts"><xsl:call-template name="GetBodyParts" /></xsl:variable>        
        <xsl:element name="note">
            <xsl:choose>
                <xsl:when test="$parts='1'">Short message</xsl:when>
                <xsl:otherwise>Long message</xsl:otherwise>
            </xsl:choose>
            from <xsl:value-of select="@sender"/>
        </xsl:element>
    </xsl:template>    
</xsl:stylesheet>
Both are sharing the same attributes.xslt: -- attributes.xslt--
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />

    <xsl:template name="GetBodyParts">
        <xsl:value-of select="*/body/@parts" />
    </xsl:template>

    <xsl:template name="GetTitle">
        <xsl:value-of select="*/header/@title" />
    </xsl:template>
</xsl:stylesheet>
If you have a close look at simpetransformation.xslt and simpletransformation2.xslt you see that they are the same except for the namespace. So I would like to move the match-parts to the attributes.xslt in order to share as much 'code' as possible. But than I need to add the "ms:" namespace at the top of attributes.xslt making it inpossible to share between the two transformations because otherwise "ms:" is not defined.

-- attributes.xslt--
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://xxxx"
xmlns:ms="http://xxxx">
    <xsl:output method="text" />

    <xsl:template name="GetBodyParts">
        <xsl:value-of select="*/body/@parts" />
    </xsl:template>

    <xsl:template name="GetTitle">
        <xsl:value-of select="*/header/@title" />
    </xsl:template>

    <xsl:template match="/ms:message">
        <xsl:variable name="parts"><xsl:call-template name="GetBodyParts" /></xsl:variable>        
        <xsl:element name="note">
            <xsl:choose>
                <xsl:when test="$parts='1'">Short message</xsl:when>
                <xsl:otherwise>Long message</xsl:otherwise>
            </xsl:choose>
            from <xsl:value-of select="@sender"/>
        </xsl:element>
    </xsl:template>    
</xsl:stylesheet>
When I remove the name spaces qualifiers everywhere than it simply does not match the message node from the message since the orignal node has been qualified with a namespace in the xml document.

-- attributes.xslt--
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0>
    <xsl:output method="text" />

    <xsl:template name="GetBodyParts">
        <xsl:value-of select="*/body/@parts" />
    </xsl:template>

    <xsl:template name="GetTitle">
        <xsl:value-of select="*/header/@title" />
    </xsl:template>

    <xsl:template match="/message">
        <xsl:variable name="parts"><xsl:call-template name="GetBodyParts" /></xsl:variable>        
        <xsl:element name="note">
            <xsl:choose>
                <xsl:when test="$parts='1'">Short message</xsl:when>
                <xsl:otherwise>Long message</xsl:otherwise>
            </xsl:choose>
            from <xsl:value-of select="@sender"/>
        </xsl:element>
    </xsl:template>    
</xsl:stylesheet>
Is there a way to make this work and to move almost everything in the shared attributes.xslt?

Any suggestion are welcomed.
Dirk



 
Old July 26th, 2007, 09:02 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>I have two xslt-transformations that are almost indentical except for the namespaces.

This is a bit like saying that two phone numbers are almost identical except for the first digit. As far as XML is concerned, if the namespaces are different then there is no relationship between the two vocabularies.

My recommendation for this problem is to preprocess one of the document types to change its namespace so that the main transformation code can then be common. It's one example of the pipeline design pattern which is the most effective way of maximizing reusability of XSLT code.

Another option which can sometimes be useful is to generate two stylesheets, one for each namespace, from a master "meta-stylesheet".

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
Default Namespace - XSLT 1.0 Geierwally XSLT 2 July 9th, 2007 11:08 AM
Nesting queries??? giffordpinchot Access 0 September 20th, 2006 09:58 AM
dynamic xslt -> xslt creation namespace problem jkmyoung XSLT 2 July 15th, 2006 12:42 AM
namespace problems in xslt stekker XSLT 2 June 16th, 2006 09:59 AM
Trouble nesting elements in a schema yossarian XML 1 February 22nd, 2005 05:30 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.