GeeCON Prague 2014*
The moose likes XML and Related Technologies and the fly likes XML Tranformation using XSLT Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Engineering » XML and Related Technologies
Bookmark "XML Tranformation using XSLT" Watch "XML Tranformation using XSLT" New topic
Author

XML Tranformation using XSLT

Swarup Sathe
Greenhorn

Joined: Aug 04, 2001
Posts: 6
Hi XML Gurus,
Need some help on XML tranformation using XSLT. I need help on coding the XSL for the requirement.I have a requirement where there are around 10 XML files where one has to Update,Delete, and insert elements in the XML document keeping the other nodes and information intact. So the input is an XML file, XSLT is used to process the document where it will update, delete, insert a elements and output is an XML document similiar to the input XML with slight changes in the elements.
I have read few documents and experimented a bit...
For copying we have code..
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="title">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
OR
<xsl:template match="title">
<xsl:copy-of select="*"/>
</xsl:template>
For Deleting:
<xsl:template match="nickname">
</xsl:template>
<xsl:template match="project[@status='canceled']">
</xsl:template>
For Updating :
<xsl:template match="article">
<html>
<xsl:apply-templates/>
</html>
</xsl:template>
If anyone has better ideas.Please let me know..
Thanks for the help in advance.
Regards
Swarup

------------------
Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
1. Copying: the second template looks correct. With the first template you may have problems: if you do not provide any template to work with children of the "title" element, XSLT processor will use built-in templates, that copy the content and leave out children enclosing tags and attributes. So for the folowing xml
<root>
<element1 id="1">content1
<element2>content2</element2>
</element1>
<element3>content3</element3>
</root>

and XSLT:
<xsl:template match="element1">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

the output will be
<element1>content1
content2
</element1>
content3

which is probably not what you want. Template2, which uses <xsl:copy-of>, is correct, it will output <title> elements "as is", with all children and all attributes.
2. Templates for deleting are correct. Only small comment: you can shorten
<xsl:template match="nickname">
</xsl:template>

as:
<xsl:template match="nickname"/>
3. Updating
Here I did not quite uderstand what kind of updating you want to achieve. How your template is written, you will get the content of the "article" element and all its children wrapped in <html> tag. Is that what you want?
[This message has been edited by Mapraputa Is (edited August 04, 2001).]


Uncontrolled vocabularies
"I try my best to make *all* my posts nice, even when I feel upset" -- Philippe Maquet
Swarup Sathe
Greenhorn

Joined: Aug 04, 2001
Posts: 6
Hi,
Thanks a lot for your reply. But can you please give me an example where there are lots of elements and nodes in the XML. How should the "copy-of select" statement work in that case.
<xsl:template match="title">
<xsl:copy-of select="*"/>
</xsl:template>

<root>
<element1 id="1">content1
<element2>content2</element2>
</element1>
<element3>content3</element3>
</root>
<xsl:template match="element1">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
The example you gave was for a small XML consider an example like this one..
<root>
<element1 id="1">content1
<element2>content2</element2>
</element1>
<element2 id="2">content2
<element2>content2</element2>
</element2>
<element3 id="3">content3
<element3>content3</element3>
</element3>
<element4 id="4">content4
<element4>content4</element4>
</element4>
<element5 id="5">content5
<element5>content5</element5>
</element5>
<element6>content6</element6>
</root>
how would u write the XSLT .....
3. Updating..
Updating a tag will be on the same lines as delete and add. So i will delete a particular element and then insert same element with different value.. Consider the following..
<element6>content6</element6>
Now I want to update the value with comtentx
I will delete the whole tag and insert a tag <element6>contentx</element6>
So what will be the XSLT code for it considering the above big XML.

My output will be again XML ONLY.
Thanks
Swarup

------------------
Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
I combined answers to both your questions in the same XSLT. If you have too many elements and (or) do not want to deal with each of them separately, you can write generic XPath to match all of them: match="root/node()" Now if you want to do something special with one of elements, "element6" in your case, you add another template with more sprecific match: match="root/element6" When XSLT processor walks through an XML document, it chooses the most specific template to apply. So all elements except "element6" will be processed by "generic" template, i.e. outputted "as is", and "element6" will be processed by dedicated template. Now, if you want to change elements' content, you can simply write it in XSLT:
<element6>contentx</element6>
and if you do not use <xsl:copy-of>, this new element will "override" the old.
The whole stylesheet will be:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<root><xsl:apply-templates/></root>
</xsl:template>
<xsl:template match="root/node()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="root/element6">
<element6>contentx</element6>
</xsl:template>
</xsl:stylesheet>

when it is run against your big XML, the output is:
<root>
<element1 id="1">content1
<element2>content2</element2>
</element1>
<element2 id="2">content2
<element2>content2</element2>
</element2>
<element3 id="3">content3
<element3>content3</element3>
</element3>
<element4 id="4">content4
<element4>content4</element4>
</element4>
<element5 id="5">content5
<element5>content5</element5>
</element5>
<element6>contentx</element6>
</root>

Swarup Sathe
Greenhorn

Joined: Aug 04, 2001
Posts: 6
Hi,
Thanks for the reply. I tried the example but it did not work..
XML file:
<?xml version="1.0"?>
<PERIODIC_TABLE>
<ATOM STATE="GAS">
<NAME>Hydrogen</NAME>
<SYMBOL>H</SYMBOL>
<ATOMIC_NUMBER>1</ATOMIC_NUMBER>
<ATOMIC_WEIGHT>1.00794</ATOMIC_WEIGHT>
<BOILING_POINT UNITS="Kelvin">20.28</BOILING_POINT>
<MELTING_POINT UNITS="Kelvin">13.81</MELTING_POINT>
<DENSITY UNITS="grams/cubic centimeter">
<!-- At 300K, 1 atm -->
0.0000899
</DENSITY>
</ATOM>
<ATOM STATE="GAS">
<NAME>Helium</NAME>
<SYMBOL>He</SYMBOL>
<ATOMIC_NUMBER>2</ATOMIC_NUMBER>
<ATOMIC_WEIGHT>4.0026</ATOMIC_WEIGHT>
<BOILING_POINT UNITS="Kelvin">4.216</BOILING_POINT>
<MELTING_POINT UNITS="Kelvin">0.95</MELTING_POINT>
<DENSITY UNITS="grams/cubic centimeter"><!-- At 300K -->
0.0001785
</DENSITY>
</ATOM>
<ATOM STATE="GAS">
<NAME>Swarup</NAME>
<SYMBOL>Sw</SYMBOL>
<ATOMIC_NUMBER>7</ATOMIC_NUMBER>
<ATOMIC_WEIGHT>7.0026</ATOMIC_WEIGHT>
<BOILING_POINT UNITS="Kelvin">7.216</BOILING_POINT>
<DENSITY UNITS="grams/cubic centimeter"><!-- At 300K -->
7.0001785
</DENSITY>
</ATOM>
</PERIODIC_TABLE>
XSL File:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl utput method="xml" indent="yes"/>

<xsl:template match="/">
<PERIODIC_TABLE><xsl:apply-templates/></PERIODIC_TABLE>
</xsl:template>
<xsl:template match="PERIODIC_TABLE/node()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="PERIODIC_TABLE/ATOM/MELTING_POINT">
<ATOM>contentx</ATOM>
</xsl:template>
</xsl:stylesheet>
Output XML File:
<?xml version="1.0" encoding="UTF-8"?>
<PERIODIC_TABLE>
<ATOM STATE="GAS">
<NAME>Hydrogen</NAME>
<SYMBOL>H</SYMBOL>
<ATOMIC_NUMBER>1</ATOMIC_NUMBER>
<ATOMIC_WEIGHT>1.00794</ATOMIC_WEIGHT>
<BOILING_POINT UNITS="Kelvin">20.28</BOILING_POINT>
<MELTING_POINT UNITS="Kelvin">13.81</MELTING_POINT>
<DENSITY UNITS="grams/cubic centimeter">
<!-- At 300K, 1 atm -->
0.0000899
</DENSITY>
</ATOM>
<ATOM STATE="GAS">
<NAME>Helium</NAME>
<SYMBOL>He</SYMBOL>
<ATOMIC_NUMBER>2</ATOMIC_NUMBER>
<ATOMIC_WEIGHT>4.0026</ATOMIC_WEIGHT>
<BOILING_POINT UNITS="Kelvin">4.216</BOILING_POINT>
<MELTING_POINT UNITS="Kelvin">0.95</MELTING_POINT>
<DENSITY UNITS="grams/cubic centimeter">
<!-- At 300K -->
0.0001785
</DENSITY>
</ATOM>
<ATOM STATE="GAS">
<NAME>Swarup</NAME>
<SYMBOL>Sw</SYMBOL>
<ATOMIC_NUMBER>7</ATOMIC_NUMBER>
<ATOMIC_WEIGHT>7.0026</ATOMIC_WEIGHT>
<BOILING_POINT UNITS="Kelvin">7.216</BOILING_POINT>
<DENSITY UNITS="grams/cubic centimeter">
<!-- At 300K -->
7.0001785
</DENSITY>
</ATOM>
</PERIODIC_TABLE>

Here I want to remove the element which does not have the MELTING-POINT Tag in it.
Thanks..
------------------
Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
Hey, it did work on your previous data!
Regarding your new data: if you want to remove the element which does not have the MELTING-POINT tag in it, you probably should not use MELTING-POINT in your match expression, because such expression will match the opposite condition. Use match="PERIODIC_TABLE/ATOM[not(MELTING_POINT)]" instead.
if you want to delete such elements, your template will look like
<xsl:template match="PERIODIC_TABLE/ATOM[not(MELTING_POINT)]"/>
Swarup Sathe
Greenhorn

Joined: Aug 04, 2001
Posts: 6
Hi,
I found out a better solution based on your input..
The XSL is as follows :
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl utput method="xml" indent="yes"/>

<xsl:template match="/">
<PERIODIC_TABLE><xsl:apply-templates/></PERIODIC_TABLE>
</xsl:template>
<xsl:template match="PERIODIC_TABLE/node()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="PERIODIC_TABLE/ATOM[not(MELTING_POINT)]">
<xsl:element name="ATOM">
<xsl:copy-of select="@*"/>
<xsl:copy-of select="node()"/>

<xsl:element name="MELTING_POINT">
<xsl:attribute name="UNITS">Kelvin</xsl:attribute>0.00</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Tell me what do you think about it.
Thanks
Swarup
 
GeeCON Prague 2014
 
subject: XML Tranformation using XSLT