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 June 17th, 2010, 11:16 AM
Registered User
 
Join Date: Jun 2010
Posts: 7
Thanks: 2
Thanked 0 Times in 0 Posts
Red face Dynamic namespaces

Hello :)

I am writing a small XSLT script to translate an incoming soap message to a simple xml data file. I am using Saxon9.

The input looks like this:
PHP Code:
<?xml version="1.0" encoding="UTF-8"?>
            <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                <SOAP-ENV:Body>
                    <ns:ContactWS_ContactQueryPage_Output
                        xmlns:ns="urn:crmondemand/ws/contact/">
                        <ns:LastPage>true</ns:LastPage>
                        <ListOfContact xmlns="urn:/crmondemand/xml/contact">
                            <Contact>
                                <ContactFirstName>Fred</ContactFirstName>
                                <IntegrationId>AAPA-1VPNO9</IntegrationId>
                                <ContactLastName>Johnson</ContactLastName>
                            </Contact>
                        </ListOfContact>
                    </ns:ContactWS_ContactQueryPage_Output>
                </SOAP-ENV:Body>
            </SOAP-ENV:Envelope>
The prefered output looks like this:
PHP Code:
<?xml version="1.0" encoding="UTF-8"?>
            <data xmlns:saxon2="http://saxon.sf.net/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:n="urn:/crmondemand/xml/contact">
                <object>
                    <property name="ContactFirstName">Fred</property>
                    <property name="replacewithidentifier">AAPA-1VPNO9</property>
                    <property name="ContactLastName">Johnson</property>
                </object>
            </data>

It works pretty well:

PHP Code:
<?xml version='1.0' encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0" xmlns:saxon2="http://saxon.sf.net/" >
    <xsl:output method='xml' />
    <xsl:variable name="modulename"><xsl:value-of select="//mappings/map[@name='module_name']" /></xsl:variable>
    <xsl:variable name="lc_modulename"><xsl:value-of select="lower-case($modulename)" /></xsl:variable>
    <xsl:variable name="crmondemand_namespace_xml">urn:/crmondemand/xml/<xsl:value-of select="$lc_modulename" /></xsl:variable>
    <xsl:template match="/">
    <data xmlns:n="urn:/crmondemand/xml/contact">
        <xsl:variable name="ListOf">//n:ListOf<xsl:value-of select="$modulename" />/n:<xsl:value-of select="$modulename" /></xsl:variable>
        <xsl:for-each select="saxon2:evaluate($ListOf)">
<object>
                <xsl:for-each select="*">
                    <xsl:element name="property">
                        <xsl:attribute name="name">
                            <xsl:choose>
                                <xsl:when test="local-name()='IntegrationId'">replacewithidentifier</xsl:when>
                                <xsl:otherwise><xsl:value-of select="local-name()" /></xsl:otherwise>
                            </xsl:choose>           
                        </xsl:attribute>
                        <xsl:value-of select="." />
                    </xsl:element>
                </xsl:for-each>
            </object>
        </xsl:for-each>
        </data>
    </xsl:template>
</xsl:stylesheet>
Now, instead of defining a concrete namespace in the data tag (<data xmlns:n="urn:/crmondemand/xml/contact">) I want to have a dynamic namespace (the content of the $crmondemand_namespace_xml variable).

How do I accomplish this?

Something like

PHP Code:
<data>
     <
xsl:namespace name="n" select="$crmondemand_namespace_xml/> 
does not work.

Thank you very much in advance

Last edited by Clemensl; June 17th, 2010 at 11:22 AM..
 
Old June 17th, 2010, 11:20 AM
samjudson's Avatar
Friend of Wrox
 
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

To create elements with dynamic namespaces I believe you would have to use the <xsl:element> instruction:

Code:
<xsl:element name="data" namespace="{$crmondemand_namespace_xml}">
  ...
</xsl:element>
__________________
/- Sam Judson : Wrox Technical Editor -/

Think before you post: What have you tried?
 
Old June 17th, 2010, 11:24 AM
Registered User
 
Join Date: Jun 2010
Posts: 7
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by samjudson View Post
To create elements with dynamic namespaces I believe you would have to use the <xsl:element> instruction:

Code:
<xsl:element name="data" namespace="{$crmondemand_namespace_xml}">
  ...
</xsl:element>
With this I get the error:
PHP Code:
Error at xsl:for-each on line 16 
  XPST0003
: Static error in XPath expression supplied to saxon2:evaluateXPath syntax error
  at char 17 in 
{//n:ListOfContact/n:Contact}:
    
Prefix n has not been declared
SystemID: ; Line#: 16; Column#: -1
net.sf.saxon.trans.XPathException: Static error in XPath expression supplied to saxon2:evaluateXPath syntax error at char 17 in {//n:ListOfContact/n:Contact}:
    
Prefix n has not been declared 
line 16 is refering to the line
PHP Code:
<xsl:for-each select="saxon2:evaluate($ListOf)"
 
Old June 17th, 2010, 11:31 AM
samjudson's Avatar
Friend of Wrox
 
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

Seems fairly self explanatory to me. The error says you haven't defined the 'n' prefix. So define it. Typical input XML namespaces are declared on the <xsl:stylesheet> element.

Code:
<xsl:stylesheet xmlns:n="urn:/crmondemand/xml/contact" ...
__________________
/- Sam Judson : Wrox Technical Editor -/

Think before you post: What have you tried?
 
Old June 17th, 2010, 11:37 AM
Registered User
 
Join Date: Jun 2010
Posts: 7
Thanks: 2
Thanked 0 Times in 0 Posts
Unhappy

Quote:
Originally Posted by samjudson View Post
Seems fairly self explanatory to me. The error says you haven't defined the 'n' prefix. So define it. Typical input XML namespaces are declared on the <xsl:stylesheet> element.

Code:
<xsl:stylesheet xmlns:n="urn:/crmondemand/xml/contact" ...
That works, but I want it to be dynamic. "contact" should be replaced by the content of the "$lc_modulename" variable...

(The module_name variables are correctly filled, I have only pasted a part of the input XML)
 
Old June 17th, 2010, 11:40 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

I might be mistaken but I think you need to create a temporary element node with the namespace declarations you want/need to use in your XPath expressions, then you can use saxon:expression with your XPath, passing in the created temporary element node as the second argument, then you can use saxon:eval on that expression:
Code:
<xsl:variable name="t1" as="element()">
  <data>
    <xsl:namespace name="n" select="$yourVariable"/>
  </data>
</xsl:variable>
<xsl:for-each select="saxon2:eval(saxon2:expression($ListOf, $t1))">
Untested!
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old June 17th, 2010, 11:41 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Presumably you also want the prefix n as used in the dynamic XPath expression to be bound to whatever namespace URI is held in the variable $crmondemandnamespace... This is a little trickier: saxon:evaluate() always binds namespace prefixes using the static namespaces declared in the stylesheet. One way out is to avoid using a namespace prefix in the dynamic XPath expression: instead of //n:ListOf<xsl:value-of select="$modulename" />, use //*:ListOf<xsl:value-of select="$modulename" /> perhaps with a predicate [namespace-uri(.) = $p1] where $p1 is the dynamic namespace, passed in as a parameter to saxon:evaluate. Another solution is to use saxon:evaluate-node(), which reads the XPath expression from a node in a document, and takes the namespace prefix bindings from the in-scope namespaces of that node; you could try creating a document dynamically with the right prefix bindings, and then using saxon:evaluate-node() to process an XPath expression held in that dynamic document.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
 
Old June 17th, 2010, 12:01 PM
Registered User
 
Join Date: Jun 2010
Posts: 7
Thanks: 2
Thanked 0 Times in 0 Posts
Smile

Quote:
Originally Posted by mhkay View Post
Presumably you also want the prefix n as used in the dynamic XPath expression to be bound to whatever namespace URI is held in the variable $crmondemandnamespace... This is a little trickier: saxon:evaluate() always binds namespace prefixes using the static namespaces declared in the stylesheet.
Ah! I didn't know that :)

Quote:
One way out is to avoid using a namespace prefix in the dynamic XPath expression: instead of //n:ListOf<xsl:value-of select="$modulename" />, use //*:ListOf<xsl:value-of select="$modulename" />
Ah that works as a workaround, thank you :)


I'll look into your other suggestions later, for now this will suffice, thank you all





Similar Threads
Thread Thread Starter Forum Replies Last Post
Namespaces Amateur BOOK: ASP.NET 2.0 Website Programming Problem Design Solution ISBN: 978-0-7645-8464-0 1 November 27th, 2006 05:19 PM
namespaces anchal C# 1 July 3rd, 2006 02:53 PM
Problems with namespaces (I think) hasanali00 BOOK: ASP.NET Website Programming Problem-Design-Solution 3 November 19th, 2005 02:05 AM
XML Namespaces billy_bob_the_3rd XML 1 January 31st, 2005 03:41 PM
NAMESPACES - WHAT ARE THEY? p_nut33 C# 2 July 31st, 2003 03:18 AM





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