Connecting Tech Pros Worldwide Forums | Help | Site Map

XSLT - How to transform Element to Attribute?

SPanicker's Avatar
Newbie
 
Join Date: Dec 2008
Location: India
Posts: 13
#1: Dec 26 '08
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.

Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,662
#2: Dec 26 '08

re: XSLT - How to transform Element to Attribute?


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
SPanicker's Avatar
Newbie
 
Join Date: Dec 2008
Location: India
Posts: 13
#3: Dec 26 '08

re: XSLT - How to transform Element to Attribute?


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.
SPanicker's Avatar
Newbie
 
Join Date: Dec 2008
Location: India
Posts: 13
#4: Dec 31 '08

re: XSLT - How to transform Element to Attribute?


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>.
Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,662
#5: Dec 31 '08

re: XSLT - How to transform Element to Attribute?


you could try a named template.

regards
SPanicker's Avatar
Newbie
 
Join Date: Dec 2008
Location: India
Posts: 13
#6: Dec 31 '08

re: XSLT - How to transform Element to Attribute?


Can you quote some example?

Regards,
SP.
Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,662
#7: Dec 31 '08

re: XSLT - How to transform Element to Attribute?


sure
Named Template Example

regards
SPanicker's Avatar
Newbie
 
Join Date: Dec 2008
Location: India
Posts: 13
#8: Dec 31 '08

re: XSLT - How to transform Element to Attribute?


Thnx.

Regards,
SP.
SPanicker's Avatar
Newbie
 
Join Date: Dec 2008
Location: India
Posts: 13
#9: Jan 6 '09

re: XSLT - How to transform Element to Attribute?


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?
Moderator
 
Join Date: Mar 2006
Posts: 1,103
#10: Jan 6 '09

re: XSLT - How to transform Element to Attribute?


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.
Reply

Tags
"transforming attribute"