Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old October 7th, 2008, 02:24 AM
Authorized User
 
Join Date: Sep 2008
Location: , , .
Posts: 26
Thanks: 2
Thanked 0 Times in 0 Posts
Default Convert nested XML to flat one

Hi, specialists! Please help me.

I need to convert nested XML to flat one:

[u]Source file:</u>

<root>
<Header>
    <Hdr>1</Hdr>
        <Order>
            <OrderNum>11</OrderNum>
            <Line>
                <LineNum>222</LineNum>
            </Line>
            <Line>
                <LineNum>333</LineNum>
            </Line>
            <Line>
                <LineNum>444</LineNum>
            </Line>
        </Order>
        <Order>
            <OrderNum>55</OrderNum>
            <Line>
                <LineNum>666</LineNum>
            </Line>
            <Line>
                <LineNum>777</LineNum>
            </Line>
        </Order>
</Header>
</root>

[u]Target:</u>


<root>
    <Header>
        <Hdr>1</Hdr>
    </Header>
    <Order>
        <OrderNum>11</OrderNum>
    </Order>
    <Line>
        <LineNum>222</LineNum>
    </Line>
     <Line>
        <LineNum>333</LineNum>
    </Line>
     <Line>
        <LineNum>444</LineNum>
    </Line>
     <Order>
        <OrderNum>55</OrderNum>
    </Order>
    <Line>
        <LineNum>666</LineNum>
    </Line>
        <Line>
        <LineNum>777</LineNum>
    </Line>
</root>

When I am using "for each" XSLT broking the order of the elements:

<root>
    <Header></Header>
    <Order></Order>
    <Order></Order>
    <Line></Line>
    <Line></Line>
    <Line></Line>
    <Line></Line>
    <Line></Line>
</root>

How can I avoid that?
Reply With Quote
  #2 (permalink)  
Old October 7th, 2008, 03:21 AM
Friend of Wrox
Points: 1,306, Level: 14
Points: 1,306, Level: 14 Points: 1,306, Level: 14 Points: 1,306, Level: 14
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2008
Location: Pondicherry, India
Posts: 291
Thanks: 9
Thanked 29 Times in 29 Posts
Default

Try this:

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

    <xsl:template match="Hdr">
        <Header>
        <xsl:copy-of select="."/>
            </Header>
    </xsl:template>

    <xsl:template match="OrderNum">
        <Order>
        <xsl:copy-of select="."/>
        </Order>
    </xsl:template>
    <xsl:template match="Line">
        <xsl:copy-of select="."/>
    </xsl:template>

Reply With Quote
  #3 (permalink)  
Old October 7th, 2008, 03:31 AM
Authorized User
 
Join Date: Sep 2008
Location: , , .
Posts: 26
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by mrame
 Try this:

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

    <xsl:template match="Hdr">
        <Header>
        <xsl:copy-of select="."/>
            </Header>
    </xsl:template>

    <xsl:template match="OrderNum">
        <Order>
        <xsl:copy-of select="."/>
        </Order>
    </xsl:template>
    <xsl:template match="Line">
        <xsl:copy-of select="."/>
    </xsl:template>
WOW! That's it!!!
mrame, thank you!

Reply With Quote
  #4 (permalink)  
Old October 7th, 2008, 04:30 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I can't tell you why your code is doing the wrong thing, because you haven't shown your code. (We may be specialists, and we do get a lot of practice, but it's still difficult to debug code when you can't see it.)

Don't use for-each, use template rules. Something like

<xsl:template match="Line">
  <xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="Order">
  <Order>
    <xsl:copy-of select="OrderNum"/>
  </Order>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="Header">
  <Header>
    <xsl:copy-of select="Hdr"/>
  </Header>
  <xsl:apply-templates/>
</xsl:template>

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Reply With Quote
  #5 (permalink)  
Old October 20th, 2008, 05:17 AM
Authorized User
 
Join Date: Sep 2008
Location: , , .
Posts: 26
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Now I have another problem. I have more complex structure:

<root>
    <Header>
        <Hdr>1</Hdr>
        <Data1>777</Data1>
        <Data2>888</Data2>
        <Data3>999</Data3>
        <Order>
            <OrderNum>11</OrderNum>
            <OrderData1>555</OrderData1>
            <OrderData2>666</OrderData2>
            <OrderData3>777</OrderData3>

            <Line>
                <LineNum>222</LineNum>
            </Line>
            <Line>
                <LineNum>333</LineNum>
            </Line>
            <Line>
                <LineNum>444</LineNum>
            </Line>
        </Order>
        <Order>
            <OrderNum>55</OrderNum>
            <OrderData1>3232</OrderData1>
            <OrderData2>5656</OrderData2>
            <OrderData3>878</OrderData3>
            <Line>
                <LineNum>666</LineNum>
            </Line>
            <Line>
                <LineNum>777</LineNum>
            </Line>
        </Order>
    </Header>
</root>

How can I transfer all those fields?
Reply With Quote
  #6 (permalink)  
Old October 20th, 2008, 05:58 AM
Friend of Wrox
Points: 1,306, Level: 14
Points: 1,306, Level: 14 Points: 1,306, Level: 14 Points: 1,306, Level: 14
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2008
Location: Pondicherry, India
Posts: 291
Thanks: 9
Thanked 29 Times in 29 Posts
Default

Try this:
  <xsl:template match="/">
        <root>
            <xsl:apply-templates/>
        </root>
    </xsl:template>

    <xsl:template match="Header">
        <Header>
            <xsl:copy-of select="Hdr"/>
        </Header>
    </xsl:template>

    <xsl:template match="Order">

        <xsl:copy-of select="OrderNum"/>

    </xsl:template>



        <xsl:template match="OrderNum"/>
    <xsl:template match="Line">
        <xsl:copy-of select="."/>
    </xsl:template>

Rummy
Reply With Quote
  #7 (permalink)  
Old October 20th, 2008, 09:43 AM
Authorized User
 
Join Date: Sep 2008
Location: , , .
Posts: 26
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Thanks Rummy. I'll try the code.

2 mhkay
Michael, you're right. I am sorry. Next time I'll attach my code.
Reply With Quote
  #8 (permalink)  
Old October 20th, 2008, 10:04 AM
Authorized User
 
Join Date: Sep 2008
Location: , , .
Posts: 26
Thanks: 2
Thanked 0 Times in 0 Posts
Default

OK, here is my code:

<?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="Line">
        <xsl:copy-of select="."/>
    </xsl:template>

    <xsl:template match="Order">
        <Order>
            <xsl:copy-of select="OrderNum"/>
            <xsl:copy-of select="OrderData1"/>
            <xsl:copy-of select="OrderData2"/>
            <xsl:copy-of select="OrderData3"/>
        </Order>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="Header">
        <Header>
            <xsl:copy-of select="Hdr"/>
            <xsl:copy-of select="Data1"/>
            <xsl:copy-of select="Data2"/>
            <xsl:copy-of select="Data3"/>
        </Header>
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>


It's working pretty good, but there is one problem, after closing the tag(for example <Header> or <Order>) I see all values in one line:



<root>
    <Header>
        <Hdr>1</Hdr>
        <Data1>777</Data1>
        <Data2>888</Data2>
        <Data3>999</Data3>
    </Header>1 777 888 999
    <Order>
        <OrderNum>11</OrderNum>
        <OrderData1>555</OrderData1>
        <OrderData2>666</OrderData2>
        <OrderData3>777</OrderData3>
    </Order>11 555 666 777
    <Line>
        <LineNum>222</LineNum>
    </Line>
    <Line>
        <LineNum>333</LineNum>
    </Line>
    <Line>
        <LineNum>444</LineNum>
    </Line>

    <Order>
        <OrderNum>55</OrderNum>
        <OrderData1>3232</OrderData1>
        <OrderData2>5656</OrderData2>
        <OrderData3>878</OrderData3>
    </Order>55 3232 5656 878
    <Line>
        <LineNum>666</LineNum>
    </Line>
    <Line>
        <LineNum>777</LineNum>
    </Line>
</root>




Reply With Quote
  #9 (permalink)  
Old October 20th, 2008, 10:18 AM
Friend of Wrox
Points: 6,676, Level: 34
Points: 6,676, Level: 34 Points: 6,676, Level: 34 Points: 6,676, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Get rid of the the xsl:apply-templates in
Code:
    <xsl:template match="Order">
        <Order>
            <xsl:copy-of select="OrderNum"/>
            <xsl:copy-of select="OrderData1"/>
            <xsl:copy-of select="OrderData2"/>
            <xsl:copy-of select="OrderData3"/>
        </Order>
        <xsl:apply-templates/>
    </xsl:template>
that way you process any child nodes and there is a built-in template that copies text nodes.
There is also an xsl:apply-templates in
Code:
    <xsl:template match="Header">
        <Header>
            <xsl:copy-of select="Hdr"/>
            <xsl:copy-of select="Data1"/>
            <xsl:copy-of select="Data2"/>
            <xsl:copy-of select="Data3"/>
        </Header>
        <xsl:apply-templates/>
that you need to remove as well.

--
  Martin Honnen
  Microsoft MVP - XML
Reply With Quote
  #10 (permalink)  
Old October 20th, 2008, 10:26 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Please don't think in terms of "closing the tag". You're writing a tree of nodes, not a sequence of start and end tags.

The reason that there's a text node after the <Order> element is that you wrote it when you did

        <Order>
            <xsl:copy-of select="OrderNum"/>
            <xsl:copy-of select="OrderData1"/>
            <xsl:copy-of select="OrderData2"/>
            <xsl:copy-of select="OrderData3"/>
        </Order>
        <xsl:apply-templates/>

If you don't want it, why are you doing the apply-templates?

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Flat XML to nested IgorK XSLT 10 November 24th, 2008 09:56 AM
Convert Flat structure to Nested dani1 XSLT 2 October 29th, 2008 02:51 AM
Help in making a FLAT xml to a structured xml shlomi XSLT 0 July 19th, 2007 07:58 AM
flat XML to hierarchical XML eduijs XSLT 1 April 28th, 2006 05:43 AM
translating a flat xml to a hierarchical xml stevea XSLT 4 June 13th, 2005 05:55 PM



All times are GMT -4. The time now is 02:22 PM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.