472,122 Members | 1,523 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,122 software developers and data experts.

XSLT - How to transform Element to Attribute?

SPanicker
Hi,

I am newbie to XSL transformations. I am finding it hard to work out the XSL transformation for the following XML. Can someone suggest me how to approach this XML or in general how should I start up if given a XML?

SOURCE XML:

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="iso-8859-1"?>
  2. <Batch BatchCreated="" TransType="TA" xmlns="http://www.w3.org/2001/xmlns">
  3. <TA>
  4. <Id>111</Id>
  5. <recipient>ABC Corp.</recipient>
  6. </TA>
  7. <CL>
  8. <id>12123</id>
  9. <claimNumber>1023-1</claimNumber>
  10. <code>Other</code>
  11. <dateReceived>01/24/2007 14:18:50</dateReceived>
  12. <policyLimit>352,000</policyLimit>
  13. <covName>Building</covName>
  14. </CL>
  15. <Contacts>
  16. <Insured>
  17. <type>client</type>
  18. <InsName>JOHN</InsName>
  19. <street>12 WALKER ST</street>
  20. <city>SIGMUND PARK</city>
  21. <state>KS</state>
  22. <country>US</country>
  23. <postal>67208</postal>
  24. <InsHomeNumber>1212151423</InsHomeNumber>
  25. <InsWorkNumber>55221155213</InsWorkNumber>
  26. <WorkExtn>123</WorkExtn>
  27. </Insured>
  28. <Claimant>
  29. <type>claimant</type>
  30. <name>MARK</name>
  31. </Claimant>
  32. </Contacts>
  33. </Batch>
  34.  
TRANSFORMED FINAL XML (what i need):

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <INFO>
  3. <TA recipient="ABC Corp." Id="111" />
  4. <CONTACTS>
  5. <CONTACT type="Client" name="JOHN">
  6. <ADDRESSES>
  7. <ADDRESS type="Property" city="SIGMUND PARK" street=">12 WALKER ST" state="KS" postal="67208" country="US" />
  8. </ADDRESSES>
  9. <CONTACTMETHODS>
  10. <PHONE type="Home" number="1212151423" extension="" />
  11. <PHONE type="Business" number="55221155213" extension="123" />
  12. </CONTACTMETHODS>
  13. </CONTACT>
  14. <CONTACT type="Claimant" name="MARK" />
  15. </CONTACTS>
  16. <LOSSDETAILS dateReceived="2007-01-24T14:18:50">
  17. <LOSS claimNumber="1023-1">
  18. <COVERAGES>
  19. <COVERAGE id="12123" covName="Building" policyLimit="3520000" />
  20. </COVERAGES>
  21. <TOL desc="Other" code="Other"></TOL>
  22. </LOSS>
  23. </LOSSDETAILS>
  24. </INFO>
  25.  
Regards,
SP.
Dec 26 '08 #1
9 8199
Dormilich
8,658 Expert Mod 8TB
basicly you need to figure out, which data structure from the input belong to which data structure in the output. use xslt to a) get the data from the former and b) write the data to the latter.

best explained in an example. let's take the <ta> tag from the input
Expand|Select|Wrap|Line Numbers
  1. <TA>
  2. <Id>111</Id>
  3. <recipient>ABC Corp.</recipient>
  4. </TA>
this will be the following in the output:
Expand|Select|Wrap|Line Numbers
  1. <TA recipient="ABC Corp." Id="111" />
so the <recipient> tag goes to the recipient attribute (same for id)
to put this into XSL
Expand|Select|Wrap|Line Numbers
  1. <xsl:template match="w3c:TA">
  2.   <TA recipient="{w3c:recipient/text()}" Id="{w3c:Id/text()}"/>
  3. </xsl:template>
what does that mean:
  • w3c:TA
    the element <TA> with its namespace (the one you defined in the <Batch> element (you can choose any namespace prefix you like).
    the template will be called if the TA node is processed
  • recipient="{w3c:recipient/text()}"
    write an attribute named "recipient" and write its content as computed from the text node of the <recipient> child node (again with namespace)
this way you can write each target element.

start the whole whole process
Expand|Select|Wrap|Line Numbers
  1. <xsl:template match="/">
  2.   <xsl:apply-templates/>
  3. </xsl:template>
don't forget to define your namespace:
Expand|Select|Wrap|Line Numbers
  1. <xsl:stylesheet version="1.0"
  2. xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  3. xmlns:w3c="http://www.w3.org/2001/xmlns">
regards
Dec 26 '08 #2
Hi Dormilich,

That was great !

Hope I can start up with this basic idea.

Will post bak if I get stuck up.Thnx :-) .


Regards,
SP.
Dec 26 '08 #3
Hi,

Referring to my previous post - how can i apply a separate template (styling) for an child element inside <xsl:template>?

For eg., if I need to apply a separate template for the contact of type 'Claimant' how can I do that?

This was what I trying but it changes the hierarchy of the XML:

Expand|Select|Wrap|Line Numbers
  1.   <xsl:template match ="Insured">
  2.     <CONTACTS>
  3.       <CONTACT type="{type/text()}" name="{name/text()}">
  4.         <ADDRESSES>
  5.           <ADDRESS type="property" city="{city/text()}" street="{street/text()}" state="{state/text()}" postal="{postal/text()}" country="US">            
  6.           </ADDRESS>
  7.           <CONTACTMETHODS>
  8.             <PHONE type="Home" number="{HomeNumber/text()}"></PHONE>
  9.             <PHONE type="Business" number="{WorkNumber/text()}" extension="{WorkExt/text()}"></PHONE>
  10.           </CONTACTMETHODS>
  11.         </ADDRESSES>
  12.       </CONTACT>
  13.       <xsl:apply-templates select ="Claimant"></xsl:apply-templates>
  14.     </CONTACTS>    
  15.   </xsl:template>
  16.  
  17.   <xsl:template match ="Claimant">
  18.     <CONTACT type="{type/text()}" name="{name/text()}">
  19.       </CONTACT>
  20.   </xsl:template>
  21.  
This is causing the second <CONTACT> element to be a child of the root element rather than being the child of <CONTACTS>.
Dec 31 '08 #4
Dormilich
8,658 Expert Mod 8TB
you could try a named template.

regards
Dec 31 '08 #5
Can you quote some example?

Regards,
SP.
Dec 31 '08 #6
Dormilich
8,658 Expert Mod 8TB
sure
Named Template Example

regards
Dec 31 '08 #7
Thnx.

Regards,
SP.
Dec 31 '08 #8
Hi,

Is there any other way to do this? I had been trying to achieve the above XML for a while and nothing helped me out.

Any suggestions on how to implement it?
Jan 6 '09 #9
jkmyoung
2,057 Expert 2GB
My guess is you'd need apply-templates to get the elements in the same order. Wasn't going to post this, since it didn't totally apply but anyways:

generic element -> attribute template
Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
  3. <xsl:template match="*">
  4.   <xsl:copy>
  5.     <xsl:for-each select="*[not(*)]">
  6.       <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
  7.     </xsl:for-each>
  8.     <xsl:apply-templates select="*[*]"/>
  9.   </xsl:copy>
  10. </xsl:template>
  11. </xsl:stylesheet>
  12.  
Specific to your problem:
1. Since you're getting rid of the namespace, replace
<xsl:copy> with <xsl:element name="local-name()">

2. Remove unnecessary nodes: eg CL, etc... seperated by |
<xsl:template match="CL|OtherNode|etc"/>

3. Have custom templates accordingly:
Expand|Select|Wrap|Line Numbers
  1. xmlns:w3="http://www.w3.org/2001/xmlns"
  2. ...
  3. <xsl:template match="w3:Batch"> 
  4.   <INFO>
  5.     <xsl:apply-templates/>
  6.   </INFO>
  7. </xsl:template>
  8. <xsl:template match ="w3:Claimant"> 
  9.   <CONTACT type="{type/text()}" name="{name/text()}"/> 
  10. </xsl:template> 
  11. <xsl:template match="w3:Insured"><!-- remove this node, but continue on. -->
  12.   <xsl:apply-templates/>
  13. </xsl:template>
  14.  
Don't know where you're getting loss details from. Assuming it's somewhere else in unposted source code.
Jan 6 '09 #10

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

3 posts views Thread by rush | last post: by
1 post views Thread by Wayne Lian via .NET 247 | last post: by
7 posts views Thread by Harolds | last post: by
7 posts views Thread by One Handed Man \( OHM - Terry Burns \) | last post: by
4 posts views Thread by David S. Alexander | last post: by
1 post views Thread by arnold | last post: by
2 posts views Thread by astroboiii | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.