This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Convert XML elements with extended attributes into CSV
- To: Xiaocun Xu <xiaocunxu at yahoo dot com>
- Subject: Re: [xsl] Convert XML elements with extended attributes into CSV
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Sat, 26 May 2001 09:31:48 +0100
- CC: xsl-list at lists dot mulberrytech dot com
- Organization: Jeni Tennison Consulting Ltd
- References: <20010526030759.51760.qmail@web11101.mail.yahoo.com>
- Reply-To: xsl-list at lists dot mulberrytech dot com
Hi Xiaocun,
> 1. Is the above solution fesible?
Yes.
> 2. Is there better way to do this?
Well, since you have the RFQExtendAttrDef elements giving you the
extended attribute definitions, you don't have to do a two-pass
solution (which is what you're describing). Instead, you iterate over
each of the LineItem elements and within that iterate over the
RFQExtendAttrDef elements to get the relevant values out:
<xsl:template match="RFQ">
<!-- set up $extended-attrs to hold the relevant extended
attributes -->
<xsl:variable name="extended-attrs"
select="RFQExtendAttrDef[@Domain = 'line_item']" />
<!-- extended attributes section -->
<!-- column specification -->
<xsl:text>Domain,Code,Name
</xsl:text>
<!-- content -->
<!-- iterate over extended attributes for content -->
<xsl:for-each select="$extended-attrs">
<xsl:value-of select="concat(@Domain, ',', @Code, ',',
@Name, '
')" />
</xsl:for-each>
<!-- line item section -->
<!-- column specification -->
<xsl:text>
Name,Category,</xsl:text>
<!-- iterate over extended attributes to get codes (or names?) -->
<xsl:for-each select="$extended-attrs">
<xsl:value-of select="@Code" />
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<!-- content -->
<!-- iterate over line items for content -->
<xsl:for-each select="LineItem">
<!-- get name and category from attributes -->
<xsl:value-of select="concat(@Name, ',', @Category, ',')" />
<!-- set up variable to hold the values of the extended
attributes on the line item -->
<xsl:variable name="line-item-attrs" select="ExtendAttr" />
<!-- iterate over the global extended attributes -->
<xsl:for-each select="$extended-attrs">
<!-- set up a variable to hold the code -->
<xsl:variable name="code" select="@Code" />
<!-- give the value of the line item's extended attribute
whose Code attribute is that code -->
<xsl:value-of select="$line-item-attrs[@Code = $code]" />
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
> 3. If there is no better way to do this, how can the first step,
> i.e. build the header node, be achieved?
You could set up a variable to hold the header node and then turn it
into a node set (rather than an RTF) so that you can use it:
<xsl:variable name="header-rtf">
<LineItemHeader>
<cell column="1">Name</cell>
<cell column="2">Category</cell>
<xsl:for-each select="$extended-attrs">
<cell column="{position() + 2}">
<xsl:value-of select="@Code" />
</cell>
</xsl:for-each>
</LineItemHeader>
</xsl:variable>
<xsl:variable name="header" select="exsl:node-set($header-rtf)" />
(Note: exsl:node-set() is supported in Saxon and 4XSLT - for other
processors you'll have to use processor-specific versions of
node-set().)
> 4. Would this solution be still fesible if the RFQExtendAttrDef
> elements does NOT exist? (this is a possibility in certain cases)
> Building the header node would require scan all LineItem elements
> for unique attributes.
Yes - it just means that you have to get the value for $extended-attrs
in a more complicated way. The easiest thing to do would be to use a
Muenchian solution. Set up a key that matches ExtendAttr elements
according to their @Code attribute:
<xsl:key name="extended-attrs" match="ExtendAttr" use="@Code" />
Then you can get the unique values with:
LineItem/ExtendAttr[count(.|key('extended-attrs', @Code)[1]) = 1]
or
LineItem/ExtendAttr[generate-id() =
generate-id(key('extended-attrs', @Code)[1])]
I hope that helps,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list