Darina Tolstykh
Darina Tolstykh

Reputation: 3

Trouble with inherent namespace XSLT

I have trouble with namespace. I need this output:

<xyt:arguments xmlns:xyt="urn:xytechsystems.com/XytechAPI"
            xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">

but have trouble with add this namespace xmlns:xyt="urn:xytechsystems.com/XytechAPI" to the argument I tried used xsl:namesapce, but think trouble in inherit with node my xslt:

?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:amc="http://schemahost.amcnetworks.com:8080/amcnesb/schemas/adam"
    xmlns:my="http://tempuri.org/dummy"
    xmlns:i ="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas" exclude-result-prefixes="#all"
    version="3.0">
    <xsl:output method="xml" encoding="UTF-8" version="1.0" indent="yes"/>

     <xsl:element name="soapenv:Envelope" >
            <xsl:namespace name="i" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
            <xsl:namespace name="xyt1"
                select="'http://schemas.datacontract.org/2004/07/Xytech.MP.API'"/>
            <xsl:namespace name="xyt" select="'urn:xytechsystems.com/XytechAPI'"/>
            <xsl:element name="soapenv:Header"/>
            <xsl:element name="soapenv:Body"/>
            <xsl:element name="xyt:Upsert">
                <xsl:element name="xyt:credentials">
                     </xsl:element>
                 <xsl:element name="xyt:arguments">
                   <xsl:namespace name="xyt" select="urn:xytechsystems.com/XytechAPI">
                   <xsl:namespace name="NS1"
                       select="'http://schemahost.amcnetworks.com:8080/amcnesb/schemas'"/>

                    

my output:

<soapenv:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:xyt1="http://schemas.datacontract.org/2004/07/Xytech.MP.API"
                  xmlns:xyt="urn:xytechsystems.com/XytechAPI"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body/>
   <xyt:Upsert>
      <xyt:credentials/>
           <xyt:arguments xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">
        <xsl:namespace name="xyt" select="'urn:xytechsystems.com/XytechAPI'"/>

Upvotes: 0

Views: 48

Answers (3)

al.truisme
al.truisme

Reputation: 534

I'm agreeing with @mads-hansen's comment:

The namespace URI is already declared with prefix xyt in an ancestor element hence will not be re-declared in the child element for the same prefix. (That's the namespace-fixup mechanism in XSLT.)

You can change the parent prefixes to be xyt1 so that the xyt prefix is new in the xyt:arguments element, even though it is the same namespace URI.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xyt1="urn:xytechsystems.com/XytechAPI"
    exclude-result-prefixes="#all"
    version="3.0">
  
    <xsl:output method="xml" encoding="UTF-8" version="1.0" indent="yes"/>

    <xsl:template name="xsl:initial-template">
      <xsl:element name="soapenv:Envelope" >
        <xsl:element name="soapenv:Header"/>
        <xsl:element name="soapenv:Body"/>
        <xsl:element name="xyt1:Upsert">
          <xsl:element name="xyt1:credentials" />
          <xsl:element name="xyt:arguments" namespace="urn:xytechsystems.com/XytechAPI">
            <xsl:namespace name="NS1" select="'http://schemahost.amcnetworks.com:8080/amcnesb/schemas'"/>
          </xsl:element>
        </xsl:element>
      </xsl:element>
    </xsl:template>
  </xsl:stylesheet>

gives

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xyt1="http://schemas.datacontract.org/2004/07/Xytech.MP.API">
   <soapenv:Header/>
   <soapenv:Body/>
   <xyt1:Upsert xmlns:xyt1="urn:xytechsystems.com/XytechAPI">
      <xyt1:credentials/>
      <xyt:arguments xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas" xmlns:xyt="urn:xytechsystems.com/XytechAPI"/>
   </xyt1:Upsert>
</soapenv:Envelope>

but I don't see why that is preferable to using the same xyt prefix everywhere in the document.

Upvotes: 0

Michael Kay
Michael Kay

Reputation: 163595

You've tagged your question xslt-1.0, but xsl:namespace is an XSLT 2.0 instruction.

Given that you're creating elements whose names are known statically, it's easiest to do this using literal result elements. Change:

<xsl:element name="soapenv:Envelope" >
            <xsl:namespace name="i" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
            <xsl:namespace name="xyt1"
                select="'http://schemas.datacontract.org/2004/07/Xytech.MP.API'"/>
            <xsl:namespace name="xyt" select="'urn:xytechsystems.com/XytechAPI'"/>
            <xsl:element name="soapenv:Header"/>
            <xsl:element name="soapenv:Body"/>
            <xsl:element name="xyt:Upsert">
                <xsl:element name="xyt:credentials">
                     </xsl:element>

to

<soapenv:Envelope 
   xmlns:i='http://www.w3.org/2001/XMLSchema-instance'
   xmlns:xyt1='http://schemas.datacontract.org/2004/07/Xytech.MP.API'
   xmlns:xyt='urn:xytechsystems.com/XytechAPI'>
   <soapenv:Header/>
   <soapenv:Body/>
   <xyt:Upsert>
     <xyt:credentials/>

Anyone who has to read your code will be eternally grateful to you.

Upvotes: 2

Martin Honnen
Martin Honnen

Reputation: 167716

If you want XSLT to output an element like e.g.

<xyt:arguments xmlns:xyt="urn:xytechsystems.com/XytechAPI"
            xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">

</xyt:arguments>

then the easiest way and the straight-forwards one is to write it as a literal result element i.e.

<xyt:arguments xmlns:xyt="urn:xytechsystems.com/XytechAPI"
            xmlns:NS1="http://schemahost.amcnetworks.com:8080/amcnesb/schemas">

</xyt:arguments>

All use of xsl:element is only needed if you want to compute the name and/or namespace (or at least parts of them) during the execution of the XSLT, based on some input data.

Upvotes: 0

Related Questions