Welcome to Dream.In.Code
Getting Help is Easy!

Join 136,158 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 2,026 people online right now. Registration is fast and FREE... Join Now!




[XSLT] transforming 1 xml to another

 
Reply to this topicStart new topic

[XSLT] transforming 1 xml to another, from 1 xml to another xml with diff layout

AngeluS
4 Jan, 2008 - 02:44 AM
Post #1

D.I.C Head
Group Icon

Joined: 10 Apr, 2007
Posts: 229


Dream Kudos: 25
My Contributions
I am trying to transform an xml file that I am getting into another one with a different layout and some extra tags.

The original xml files I am getting from a process that is fetching this data out of a CSV file so I am unable to change these xml files...

The original file I get is:
CODE

<?xml version="1.0"?>
<Calendars>
        <currency>AED</currency>
        <description>UAE DIRHAM</description>
        <weekday>Friday</weekday>
        <weekday></weekday>
        <weekday></weekday>
        <weekday></weekday>
        <weekday></weekday>
        <weekday></weekday>
        <weekday></weekday>
        <holiday>20051203</holiday>
        <holiday>20060101</holiday>
        <holiday>20060105</holiday>
        <holiday>20060107</holiday>
        <holiday>20060108</holiday>
        <holiday>20060109</holiday>
        <holiday>20060110</holiday>
</Calendars>


The XSLT file that I have made and using for the transformation is:
CODE

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mx="http://murex.com/xslt/common" exclude-result-prefixes="mx">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">        
        <Calendars>
                <calendar id="cal_0">
                        <businessObjectId mefClass="mxStaticsDatesICALENDAR">
                        <identifier><xsl:value-of select="Calendars/currency"/></identifier>
                        </businessObjectId>
                        <description><xsl:value-of select="Calendars/description"/></description>
                        <swiftCode></swiftCode>
                        <holidaysPattern>
                                <weekdays>
                                        <weekday><xsl:copy-of select="Calendars/weekday"/></weekday>
                                </weekdays>
                                <yearlyDates></yearlyDates>
                                <specialDates>
                                                <date><xsl:copy-of select="Calendars/holiday"/></date>
                                </specialDates>
                        </holidaysPattern>
                </calendar>
        </Calendars>
        </MxML>
</xsl:template>
</xsl:stylesheet>


The result I get out of that one is:
CODE

<?xml version="1.0" encoding="UTF-8"?>
<MxML version="1-1">
        <Calendars>
                <calendar id="cal_0">
                        <businessObjectId mefClass="mxStaticsDatesICALENDAR">
                                <identifier>AED</identifier>
                        </businessObjectId>
                        <description>UAE DIRHAM</description>
                        <swiftCode/>
                        <holidaysPattern>
                                <weekdays>
                                        <weekday>
                                                <weekday>Friday</weekday>
                                                <weekday/>
                                                <weekday/>
                                                <weekday/>
                                                <weekday/>
                                                <weekday/>
                                                <weekday/>
                                        </weekday>
                                </weekdays>
                                <yearlyDates/>
                                <specialDates>
                                        <date>
                                                <holiday>20051203</holiday>
                                                <holiday>20060101</holiday>
                                                <holiday>20060105</holiday>
                                                <holiday>20060107</holiday>
                                                <holiday>20060108</holiday>
                                                <holiday>20060109</holiday>
                                                <holiday>20060110</holiday>
                                        </date>
                                </specialDates>
                        </holidaysPattern>
                </calendar>
        </Calendars>
</MxML>


HOWEVER!! I still need to get rid of the "empty" weekday tags (<weekday/>) And I can't seem to find on how to do that.
Who can help me?
User is offlineProfile CardPM
+Quote Post

baavgai
RE: [XSLT] Transforming 1 Xml To Another
4 Jan, 2008 - 05:59 AM
Post #2

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,019



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
I think this is what you're looking for:
CODE

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/">
        <xsl:apply-templates select="Calendars"/>
    </xsl:template>
    
    <xsl:template match="Calendars">
        <Calendars>
            <calendar id="cal_0">
                <businessObjectId mefClass="mxStaticsDatesICALENDAR">
                    <identifier><xsl:value-of select="currency"/></identifier>
                </businessObjectId>
                <description><xsl:value-of select="description"/></description>
                <swiftCode></swiftCode>
                <holidaysPattern>
                    <weekdays><xsl:apply-templates select="weekday"/></weekdays>
                    <yearlyDates></yearlyDates>
                    <specialDates><xsl:apply-templates select="holiday"/></specialDates>
                </holidaysPattern>
            </calendar>
        </Calendars>
    </xsl:template>
    
    <xsl:template match="weekday">
        <weekday><xsl:value-of select="."/></weekday>
    </xsl:template>

    <xsl:template match="holiday">
        <date><xsl:value-of select="."/></date>
    </xsl:template>

    <!-- ditch the empties -->
    <xsl:template match="*[not(node())]"></xsl:template>

</xsl:stylesheet>


Note, the order of templates is important. The entries farther down in the file will override prior entries. So, the weekday template matches, unless it is empty, then it matches empty template instead.

Hope this helps.

User is offlineProfile CardPM
+Quote Post

AngeluS
RE: [XSLT] Transforming 1 Xml To Another
4 Jan, 2008 - 06:58 AM
Post #3

D.I.C Head
Group Icon

Joined: 10 Apr, 2007
Posts: 229


Dream Kudos: 25
My Contributions
yub yub; your solution works perfectly. + it explains a bit more on the whole template thingy for me. thanks
User is offlineProfile CardPM
+Quote Post

AngeluS
RE: [XSLT] Transforming 1 Xml To Another
8 Jan, 2008 - 02:21 AM
Post #4

D.I.C Head
Group Icon

Joined: 10 Apr, 2007
Posts: 229


Dream Kudos: 25
My Contributions
Another issue that I have now is that I have to get rid of quotes (") in strings.
I know that I will need to use a substring or replace function or something else but I don't know if I should do this as a separate part in a "template match" like in the example to delete the empty nodes or if I should do this in the template that is handling that specific tag which needs the quotes removed.
anyone?
User is offlineProfile CardPM
+Quote Post

baavgai
RE: [XSLT] Transforming 1 Xml To Another
8 Jan, 2008 - 06:33 AM
Post #5

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,019



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
Keeping in mind that while XSLT is ideal for manipulating XML nodes, it's pretty challenged when it comes to string manipulation.

Here's one way to do it.

CODE

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/">
        <xsl:apply-templates select="Calendars"/>
    </xsl:template>
    
    <xsl:template match="Calendars">
        <Calendars>
            <calendar id="cal_0">
                <businessObjectId mefClass="mxStaticsDatesICALENDAR">
                    <identifier><xsl:value-of select="currency"/></identifier>
                </businessObjectId>
                <!-- <description><xsl:value-of select="description"/></description> -->
                <description>
                    <xsl:call-template name="removeChar">
                        <xsl:with-param name="string" select="description" />
                        <xsl:with-param name="removeValue" select="'"'" />
                    </xsl:call-template>
                </description>

                <swiftCode></swiftCode>
                <holidaysPattern>
                    <weekdays><xsl:apply-templates select="weekday"/></weekdays>
                    <yearlyDates></yearlyDates>
                    <specialDates><xsl:apply-templates select="holiday"/></specialDates>
                </holidaysPattern>
            </calendar>
        </Calendars>
    </xsl:template>
    
    <xsl:template match="weekday">
        <weekday><xsl:value-of select="."/></weekday>
    </xsl:template>

    <xsl:template match="holiday">
        <date><xsl:value-of select="."/></date>
    </xsl:template>

    <!-- ditch the empties -->
    <xsl:template match="*[not(node())]"></xsl:template>
    
    <xsl:template name="removeChar">
        <xsl:param name="string" />
        <xsl:param name="removeValue" />
        <xsl:if test="contains($string, $removeValue)">
            <xsl:value-of select="substring-before($string, $removeValue)" />
            <xsl:call-template name="removeChar">
                <xsl:with-param name="string" select="substring-after($string, $removeValue)" />
                <xsl:with-param name="removeValue" select="$removeValue" />
            </xsl:call-template>
        </xsl:if>
        <xsl:if test="not(contains($string, $removeValue))">
            <xsl:value-of select="$string" />
        </xsl:if>
    </xsl:template>
    
</xsl:stylesheet>


I adapted this from Dave Pawson's excellent XSLT Site, which it worth a bookmark if you're playing with stylesheets.

User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/1/08 11:37PM

Live Help!

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month