This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Converting XML source to CSV output


On Wed, Sep 19, 2001 at 02:41:08PM -0400, Chris Pearson wrote:
> Hi all.  A novice question that I can't seem to locate a solution for
> ...  I have an XML source that I need to convert to a text delimited
> file.  
> 
> The xml source is:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <DATA>
>    <HEADER>
>       <RECORD_A value="Header1 Record A" />
>       [...]
>    </HEADER>
>    <BODY>
>       <BODY_RECORD_A value="Body1 Record A" />
>	[...]
>       <DETAIL>
>          <DET_RECORD_A value="Detail1 Record A" />
>	   [...]
>       </DETAIL>
> [...]
>    </BODY>
> </DATA>
> 
> ++++++++++++++++++++++++++++++++++++++
> 
> What I want is:
> 
> Header1 Record A,Header1 Record B,Header1 Record n,Body1 Record A,Body1
> Record B,Body1 Record n,Detail1 Record A,Detail1 Record B,Detail1 Recordn
[...]

The values you use to demonstrate the sample output are a little verbose
and difficult to follow.  I'm assuming that you're looking for something
like this:

head1a, head1b, head1n, body1a, body1b, body1n, detail1a, detail1b, detail1n
head1a, head1b, head1n, body1a, body1b, body1n, detail2a, detail2b, detail2n
head1a, head1b, head1n, body2a, body2b, body2n, detail3a, detail3b, detail3n
head1a, head1b, head1n, body2a, body2b, body2n, detail4a, detail4b, detail4n

> I'm having 2 issues:
> 
> 1) How to repeat the header (and Body data) for detail records

Your stylesheet, although not wrong, is a little difficult to follow.
Essentially, what you're doing is processing blocks of <detail> elements
and including <header> and <body> elements for each set of <detail> elements
you find.

Try this template instead:

<xsl:template match="body/detail">
 <!-- Grab all of the relevant blocks for this set of detail elements -->
 <!-- (just for clarity and convenience -->
 <xsl:variable name="header" select="/data/header/*/@value"/>
 <xsl:variable name="body" select="parent::*/*/@value"/>
 <xsl:variable name="self" select="*/@value"/>

 <!-- aggregate them for convenience -->
 <xsl:variable name="all-elements" select="$header | $body | $self"/>


 <!-- Process -->
 <xsl:for-each select="$all-elements[position() != last()]">
  <xsl:value-of select="concat(., ', ')"/>
 </xsl:for-each>

 <xsl:value-of select="concat($self[last()], '&#xa;')"/>

</xsl:template>

> 2) How to format it without extra white space

You probably forgot to ignore text nodes:

 <xsl:template match="text()"/>

HTH,

Z.


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]