Subject: Re: [xsl] Convert XML elements with extended attributes into CSV From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Sat, 26 May 2001 09:31:48 +0100 |
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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Convert XML elements with ext, Xiaocun Xu | Thread | [xsl] conditional tree variables, Mattias Konradsson |
RE: [xsl] javax.xml.transform: proh, Julian Reschke | Date | [xsl] conditional tree variables, Mattias Konradsson |
Month |