how to convert One format Xml to another format Xml?

Questions about XML that are not covered by the other forums should go here.
wangyf2010
Posts: 1
Joined: Tue Nov 22, 2005 12:17 pm

how to convert One format Xml to another format Xml?

Post by wangyf2010 »

It'll be a jscript function to transform a given format of XML input to another XML format.

The input would be like:


<?xml version="1.0"?>
<menu xmlns="">
<menuitem>
<node>1</node>
<parent>1</parent>
<name>parent</name>
</menuitem>
<menuitem>
<node>2</node>
<parent>1</parent>
<name>1st child</name>
</menuitem>
<menuitem>
<node>3</node>
<parent>1</parent>
<name>2nd child</name>
</menuitem>
<menuitem>
<node>4</node>
<parent>2</parent>
<name>grantchild</name>
<attr1>hello</attr1>
<attr2>World</attr2>
</menuitem>
</menu>

The output would be like:

<?xml version="1.0"?>
<menu xmlns="">
<menuitem>
<name>parent</name>
<menuitem>
<name>1st child</name>
<attr1>hello</attr1>
<attr2>World</attr2>
<menuitem>
<name>grand child</name>
</menuitem>
</menuitem>
<menuitem>
<name>2nd child</name>
</menuitem>
</menuitem>
</menu>

In the input format, tag "node" and "parent" specifies the structure of the tree, while "name" and others tags should be copied to the output format. Therefore, the code should be able to handle the following fragment of XML:

<menuitem>
<node>2</node>
<parent>1</parent>
<name>1st child</name>
<lastName>Xia</lastName>
<firstName>Hao</firstName>
</menuitem>

:shock:
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi,

You can have a key to select all the menu items that have a specific parent. Please note that you have a recursive parent in your sample XML file, the first menu item has itself as parent, you need to change that. You can find below a working sample that should give you the idea:

Code: Select all


<?xml version="1.0"?>
<menu>
<menuitem>
<node>1</node>
<parent>0</parent>
<name>parent</name>
</menuitem>
<menuitem>
<node>2</node>
<parent>1</parent>
<name>1st child</name>
</menuitem>
<menuitem>
<node>3</node>
<parent>1</parent>
<name>2nd child</name>
</menuitem>
<menuitem>
<node>4</node>
<parent>2</parent>
<name>grantchild</name>
<attr1>hello</attr1>
<attr2>World</attr2>
</menuitem>
</menu>

Code: Select all


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output indent="yes"/>
<xsl:key name="children" match="menuitem" use="parent"/>

<xsl:template match="menu">
<xsl:apply-templates select="menuitem[1]"/>
</xsl:template>

<xsl:template match="menuitem">
<menuitem>
<xsl:apply-templates mode="copy"/>
<xsl:apply-templates select="key('children', node)"/>
</menuitem>
</xsl:template>

<xsl:template match="name|attr1|attr2" mode="copy">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*" mode="copy"/>
</xsl:stylesheet>
The result is:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<menuitem xmlns:fo="http://www.w3.org/1999/XSL/Format">
<name>parent</name>
<menuitem>
<name>1st child</name>
<menuitem>
<name>grantchild</name>
<attr1>hello</attr1>
<attr2>World</attr2>
</menuitem>
</menuitem>
<menuitem>
<name>2nd child</name>
</menuitem>
</menuitem>
Best Regards,
George
vrkanth2
Posts: 6
Joined: Wed Nov 23, 2005 12:55 am

Post by vrkanth2 »

Hi George,
I have similar need to change the XML file from one format to another format. I have read you answer and the example, I am feeling very difficult to under stand the XSLT file as I am new to XSLT. Can you please provide me some explanation for this XSLT file or can you suggest me where I can XSLT with XML to XML transformation.


Thanks a lot,
Raj
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi Raj,

See below comments about the above stylesheet:

Code: Select all


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="children" match="menuitem" use="parent"/>
The key defines a map, the key of the map is the value of the parent element and the values associated with the key are menuitem elements that have that value for the parent subelement. For instance if you invoke then the key for the value 1 it will return two menuitem elements, the one with node 2 and the one with node 3.

Code: Select all


   
<xsl:template match="menu">
<xsl:apply-templates select="menuitem[1]"/>
</xsl:template>
This templates matches on the root element and applies the other templates on the first menuitem (I assumed the first menuitem is the root).

Code: Select all


   
<xsl:template match="menuitem">
<menuitem>
<xsl:apply-templates mode="copy"/>
<xsl:apply-templates select="key('children', node)"/>
</menuitem>
</xsl:template>
This template matches a menuitem and creates a menuitem element to the output and inside that element places the result of applying the templates that have the mode set to "copy" on the matched menuitem content and the result of applying the templates on the children of this node (we call the mapping passing this node value for the key, see the above explanation at the key definition). This will cause the children menuitem to appear inside the parent menuitem and the templates with mode copy will place only the content of the menuitem that we want to keep inside.

Code: Select all



<xsl:template match="name|attr1|attr2" mode="copy">
<xsl:copy-of select="."/>
</xsl:template>
This template is in the "copy" mode and matches the elements we want to keep inside a menuitem. Matched elements are copied as they are to the output.

Code: Select all



<xsl:template match="*" mode="copy"/>
This template is in the "copy" mode and matched other elements (that we do not want to copy to the output). In this case this will match parent and node for instance. As the template does notheing they will be ignored.

Code: Select all



</xsl:stylesheet>
Jeni Tennison's books are very good for understanding XSLT, you can find them together with other very good XSLT books on our books section:
http://www.oxygenxml.com/xml_books.html

Best Regards,
George
vrkanth2
Posts: 6
Joined: Wed Nov 23, 2005 12:55 am

Post by vrkanth2 »

Hi George,
Thanks a lot for explanation, I studied a tutorial on XSLT and your explanation, I copied your example codes both input file and XSLT file into a folder and I gave a href link to XSL file in input XML file, the result I got was a HTML file not another XML file. Resulting page was displayed like this:

Parent 1child Grandchild helloworld 2ndchild

and I put this line in input xml file

<?xml-stylesheet type="text/xsl" href="stylesheetname.xsl"?>

Am I doing some thing wrong?

Thank you,
Raj
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi Raj,

The result should be what I posted:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<menuitem xmlns:fo="http://www.w3.org/1999/XSL/Format">
<name>parent</name>
<menuitem>
<name>1st child</name>
<menuitem>
<name>grantchild</name>
<attr1>hello</attr1>
<attr2>World</attr2>
</menuitem>
</menuitem>
<menuitem>
<name>2nd child</name>
</menuitem>
</menuitem>
and the browser renders that as you describe.

If you want HTML as output you need to change the XSLT to generate HTML.

Best Regards,
George
vrkanth2
Posts: 6
Joined: Wed Nov 23, 2005 12:55 am

Post by vrkanth2 »

Hi George,
Thanks for quick response, I want XML output only, but as I mentioned I am getting only the text in a single line

Parent 1child Grandchild helloworld 2ndchild

do you think I am doing some thing wrong when referencing to XSL file?


Thank you,
Raj
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi Raj,

I think you let the browser apply the transformation by loading the xml file in the browser, right?
You need to execute the transformation in some other way, from oXygen for instance or from command line if you wish. For the first check the oXygen user guide and for the second look at the command line options for the XSLT processor of your choice.

Best Regards,
George
vrkanth2
Posts: 6
Joined: Wed Nov 23, 2005 12:55 am

Post by vrkanth2 »

Hi George,
Yes, I left the browser apply the transformations. But, now I tried with Oxygen, it is working, I got the correct out put. Thanks a lot, I am going to try my XML file, I feel I can do it soon easily with the help of Oxygen.



Thanks again,
Raj
Post Reply