Solved

transforming XML with namspaces to XML using XSL

Posted on 2007-11-27
12
409 Views
Last Modified: 2013-11-18
Hi folks:

Somehow I can't figure out why XML is not correctly transformed when it contains namepspace(s). When it does not contain namesspace(s) the transformation works as expected.

I tried the following xml and XSL

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="organization_01.xsl"?>
<rxraza:Organization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:rxraza="http://some_name_space">
  <rxraza:Data>
    <rxraza:Field1>1001</rxraza:Field1>
  </rxraza:Data>
</rxraza:Organization>

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rxraza="http://some_name_space">
  <xsl:output method="xml"/>
 
  <xsl:template match="/">
    <xsl:element name="Organization">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
 
  <xsl:template match="rxraza:Data">
   
      <xsl:for-each select="/rxraza:Organization/rxraza:Data">
        <xsl:element name='{name()}'>
          <xsl:for-each select="*" >
            <xsl:element name='{name()}'>
              <xsl:value-of select="."/>
            </xsl:element>
          </xsl:for-each>
        </xsl:element>
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

and the output that I got is as follows:

<?xml version="1.0" encoding="utf-16"?><Organization>1001</Organization>

where as I should have gotten the following

<?xml version="1.0" encoding="utf-16"?><Organization><Data><Field>1001</Field></Data></Organization>

Thanks in advance
0
Comment
Question by:rxraza
  • 6
  • 6
12 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 20363685
that is strange.
Your XSLT does exactly what it should do on my machine
The tags are there, but maybe in the wrong namespace
(by using name() you pass the namespace as well

I have simplified your XSLT a bit

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:rxraza="http://some_name_space"
     exclude-result-prefixes="rxraza">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

note that it is important when you work with namespaces
that the url (not necesarily the prefix) is equal on both sides of he equation
0
 

Author Comment

by:rxraza
ID: 20366115
How did you test it. Did you open the XML in the IE browser?
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 20366168
No, opening in a browser is no good.

I tested this using an Integrated Development Environment, that I use for XSLT development
In this case I used Oxygen (www.oxygenxml.com)
That is the only way to decently debug an XSLT

If you view the result in a browser, you will not see the tags that are not html
(because the browser is set to ignore the tags outside the html namespace)

You could transform the XML using XSLT outside a browser, on the command line
(eg. using msxsl, xalan or saxon)
and then view the xml in the treeview in the browser,
but then you look at it as XML, not as HTML

I hope this helps

Geert
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 

Author Comment

by:rxraza
ID: 20366296
Yes you are right. I tested mine with C# code. Anyways, you gave me enough clues to figure out the problem. The xsl file being pointed was different. :-)
0
 

Author Comment

by:rxraza
ID: 20366716
Gertone:

Thanks for assisting me so far. I got a more complex xml structure now and I applied the same logic but am not getting the desired results

The result that I am getting is

<Organization>1001</Organization>

instead of getting

<Organization><OrganizationChild></OrganizationChild></Organization>

Following is the XML and XSL

<?xml version="1.0" encoding="iso-8859-1" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Header>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <ns1:NodeA xmlns:ns1="namespace1" xmlns:ns2="http://namespace2">
      <ns2:Organization>
        <ns2:Data>
          <ns2:Field>1001</ns2:Field>
        </ns2:Data>
      </ns2:Organization>
    </ns1:NodeA>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:SOAP-ENV="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ns1="http://namespace1"
  xmlns:ns2="http://namespace2"
>
  <xsl:output method="xml" encoding="UTF-8" />

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

  <xsl:template match="SOAP-ENV:Body">
    <xsl:element name="OrganizationChild">
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Am I missing something here? Thanks in advance
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 20367809
you simply had the wrong namespace URI for SOAP-ENV
I also made some changes to your stylesheet to simplyfy it

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="http://namespace1"
    xmlns:ns2="http://namespace2"
    >
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
   
    <xsl:template match="SOAP-ENV:Body">
        <xsl:element name="Organization">
            <xsl:element name="OrganizationChild">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

cheers

Geert
0
 

Author Comment

by:rxraza
ID: 20378576
Gertone:

You have been awesome in pointing errors. I got another trouble. For the following changed XSL I am not getting the desired result

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ns1="http://namespace1"
  xmlns:ns2="http://namespace2"
>
  <xsl:output method="xml" encoding="UTF-8"/>

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

  <xsl:template match="SOAP-ENV:Body">
    <xsl:for-each select="/SOAP-ENV:Envelope/SOAP-ENV:Body/ns1:NodeA/ns2:Organization/ns2:Data">
      <xsl:element name="transformedData"></xsl:element>
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

What I am getting is following

<?xml version="1.0" encoding="utf-16"?><Organization />

as opposed to the desired following

<?xml version="1.0" encoding="utf-16"?><Organization><tranaformedData></transformedData></Organization>

Am I missing something again ? I would appreciate any help in this matter.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 20378599
change this template

<xsl:template match="SOAP-ENV:Body">
    <xsl:for-each select="ns1:NodeA/ns2:Organization/ns2:Data">
      <xsl:element name="transformedData"></xsl:element>
      </xsl:for-each>
  </xsl:template>

in the template matching SOAP-ENV:Body, you should use the context
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 20378623
on top of that, your namespaces strings are not equal
    xmlns:ns1="namespace1"
and
    xmlns:ns1="http://namespace1"

they need to be identical strings in both XML and XSLT
0
 

Author Comment

by:rxraza
ID: 20399834
Thanks Gertone for all the feedbacks. One final question. If a schema contains references to other schemas do we have to include all schemas in the XSL stylesheet in its stylesheet  element even though those elements are not even used ?
0
 

Author Closing Comment

by:rxraza
ID: 31411337
you truly are a GENIUS
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 20401360
welcome

you only need to reference the namespaces that are used in the stylesheet
The stylesheet is XML, so you have to make sure that teh XSLT is wellformed
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Adding Namespace to the second node of the xml 16 78
Formatting issues in XSL FO 3 44
Excel file not created as expected 7 79
Xsl-fo show PDF when no results are returned 2 20
This article covers the basics of the Sass, which is a CSS extension language. You will learn about variables, mixins, and nesting.
Introduction Since I wrote the original article about Handling Date and Time in PHP and MySQL (http://www.experts-exchange.com/articles/201/Handling-Date-and-Time-in-PHP-and-MySQL.html) several years ago, it seemed like now was a good time to updat…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question