RE: RE: [xsl] How to implement an array

Subject: RE: RE: [xsl] How to implement an array
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Fri, 14 Feb 2003 14:53:36 -0500

At 10:34 AM 2/14/2003, you wrote:
When no row in the table contains any element for a
particular column that column is excluded from the
colum heading. But the above template would insert a
blank cell in the table. So we get
Heading: Col1 Col2 Col3
Data     XXX   YYY      ZZZ
Data     XXX   YYY      ZZZ

instead of:
Heading: Col1 Col2 Col3
Data     XXX   YYY ZZZ
Data     XXX   YYY ZZZ

I think it is necessary to check if elements exist for
all children nodes before inserting a cell data (<td>
element). That was the logic I was struggling with.

Well yes; and it comes back to whether your tables are static and known ahead of time, or whether they have to be constructed dynamically. The code I provided assumes your lookup node set (which functions as kind of a template, as you can see, for an HTML table in output) is complete and that all derived tables will reflect all the "cells" it specifies. The problem you are describing now is due to this assumption's not holding in your case.

Therefore, you need to do a bit more work to derive what the node set needs to be in a particular instance; your lookup node set is a starting point, but in your first template it needs to be stripped of any nodes you won't want; then the resulting filtered node set must be passed to the second template to walk through, building its rows.

Unfortunately, because of the way you are testing things -- by element name -- this is actually less easy (much less!) to do than it could be. It would be much much easier if your input looked (for example) like this:

[lookup table]

  <row name="Item">
    <cell name="ItemLine">Required</cell>
    <cell name="ItemAcct">Required</cell>
    <cell name="Option">Optional</cell>
    <cell name="ItemText">Required</cell>

[input data]

    <cell name="ItemLine">3</cell>
    <cell name="ItemAcct">6</cell>
    <cell name="Option">Contains Data1</cell>
    <cell name="ItemText">This is line 3</cell>

I don't know whether this is an option for you; given the kind of processing you are trying to perform, however, it'd be much nicer from an XSLT point of view, since now the things you need to test against (the names of your cells) are available as the values, not just the names, of nodes. XSLT can collect nodes and test their values against each other in entire sets; whereas names it can only look at one at a time.

(Critical to understanding the last detail is the fact that $nodeset1 = $nodeset2 in XPath1 if $nodeset1 contains *any* node with *value* the same as *any* node in $nodeset2. This is a very useful feature when we need to filter node sets based on the values of their nodes.)

If this is not an option and you have to work with the input format you have (note the one I suggest can be trivially created from what you have with a simple transform), your problem is still solvable, though nastier. Two possible approaches come to mind: one uses a node-set() extension function to create new node sets; another resorts to horrible string-construction-and-testing hackery....

Sorry I can't be more help today--


====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================

XSL-List info and archive:

Current Thread