472,101 Members | 1,406 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

XSLT: how to create dynamic elemant name?

Hi All,

I am newbie to XSLT, so I need some help from you guys.
I need to create the XSLT file to transform the element 'name' to 'bname1' and 'bname2' respectively (please see source and required xml below). Could anyone please give me a hint how to do it. Thank you for any help in advance.

Source XML

<books>
<book>
<name>bookname</name>
<name>authorname</name>
</book>
</books>

Required XML

<books>
<book>
<bname1>bookname</bname1>
<bname2>authorname</bname2>
</book>
</books>
Jan 11 '08 #1
3 28550
jkmyoung
2,057 Expert 2GB
- Use <xsl:number> to get the right number.
- Store the element name in a variable.
- Declare the element. Use braces {} to get the value of the name attribute from the variable.
Expand|Select|Wrap|Line Numbers
  1. <xsl:template match="name">
  2.   <xsl:variable name="ename">
  3.     <xsl:text>bname</xsl:text>
  4.     <xsl:number count="name"/>
  5.   </xsl:variable>
  6.  
  7.   <xsl:element name="{$ename}">
  8.      <xsl:value-of select="."/>
  9.   </xsl:element>
  10. </xsl:template>
  11.  
Jan 11 '08 #2
Thank you jkmyoung. I have applied your idea to what I want to do, but when I have more elements, the xsl:variable value did not not change, so I got the wrong result. Please see below for more information what I've done.

Source XML.

<Delivery>
<ShipTo>
<Name>Jame Good</Name>
<Name>A Com.</Name>
<Address>A Street</Address>
<Address>A City</Address>
</ShipTo>
<BillTo>
<Name>Bill Good</Name>
<Name>B Com.</Name>
<Address>B City</Address>
<Address>B City</Address>
<Address>B State</Address>
</BillTo>
</Delivery>

Existing XSL.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/Delivery">
<Delivery>
<xsl:apply-templates/>
</Delivery>
</xsl:template>

<xsl:template match="//*/Name">
<xsl:variable name="newname">
<xsl:choose>
<xsl:when test="//ShipTo/Name">
<xsl:text>ShipToName</xsl:text>
</xsl:when>
<xsl:when test="//BillTo/Name">
<xsl:text>BillToName</xsl:text>
</xsl:when>
</xsl:choose>
<xsl:number count="Name"/>
</xsl:variable>
<xsl:element name="{$newname}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>

<xsl:template match="//*/Address">
<xsl:variable name="newname">
<xsl:choose>
<xsl:when test="//ShipTo/Address">
<xsl:text>ShipToAddress</xsl:text>
</xsl:when>
<xsl:when test="//BillTo/Address">
<xsl:text>BillToAddress</xsl:text>
</xsl:when>
</xsl:choose>
<xsl:number count="Address"/>
</xsl:variable>
<xsl:element name="{$newname}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

Existing result which is still wrong.

<?xml version="1.0" encoding="UTF-8"?>
<Delivery>

<ShipToName1>Jame Good</ShipToName1>
<ShipToName2>A Com.</ShipToName2>
<ShipToAddress1>A Street</ShipToAddress1>
<ShipToAddress2>A City</ShipToAddress2>

<ShipToName1>Bill Good</ShipToName1> * the name did not change to BillToName1
<ShipToName2>B Com.</ShipToName2> * the name did not change to BillToName2
<ShipToAddress1>B Street</ShipToAddress1> * the name did not change to BillToAddress1
<ShipToAddress2>B City</ShipToAddress2> * the name did not change to BillToAddress2
<ShipToAddress3>B State</ShipToAddress3> * the name did not change to BillToAddress3

</Delivery>


The required result XML

<Delivery>
<ShipToName1>Jame Good</name>
<ShipToName2>A Com.</name>
<ShipToAddress1>A Street</ShipToAddress1>
<ShipToAddress2>A City</ShipToAddress2>
<BillToName1>Bill Good</BillToName1>
<BillToName2>Bill Good</BillToName2>
<BillToAddress1>B Com.</BillToAddress1>
</Delivery>


Can anyone suggest me how to fix the xsl to get the result as requirement please. Thank you advance.
Jan 13 '08 #3
Finally, I get it done myself with the following code.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" xalan:indent-amount="2" xmlns:xalan="http://xml.apache.org/xslt"/>

<!-- Remove blank line -->
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>

<xsl:template match="//ShipTo | //BillTo ">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="//ShipTo/*">
<xsl:choose>
<xsl:when test="local-name(.) = 'Name'">
<xsl:call-template name="Name">
<xsl:with-param name="word" select="'ShipToName'"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="local-name(.) = 'Address'">
<xsl:call-template name="Address">
<xsl:with-param name="word" select="'ShipToAddress'"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>

<xsl:template match="//BillTo/*">
<xsl:choose>
<xsl:when test="local-name(.) = 'Name'">
<xsl:call-template name="Name">
<xsl:with-param name="word" select="'BillToName'"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="local-name(.) = 'Address'">
<xsl:call-template name="Address">
<xsl:with-param name="word" select="'BillToAddress'"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>

<xsl:template name="Name">
<xsl:param name="word"/>
<xsl:variable name="newname">
<xsl:value-of select="$word"/>
<xsl:number count="Name"/>
</xsl:variable>
<xsl:element name="{$newname}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>

<xsl:template name="Address">
<xsl:param name="word"/>
<xsl:variable name="newname">
<xsl:value-of select="$word"/>
<xsl:number count="Address"/>
</xsl:variable>
<xsl:element name="{$newname}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>

<!-- Copy other elements -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>
Jan 14 '08 #4

Post your reply

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

Similar topics

4 posts views Thread by Son KwonNam | last post: by
1 post views Thread by Ric Castagna | last post: by
5 posts views Thread by Sunil Varma | 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.