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]
Other format: [Raw text]

Re: Newbie - simple selection problem


Hi Jim,

There are two things in XPath that look very similar to each other:
paths that select nodes and patterns that match nodes. You're
confusing the two.

The match attribute of xsl:template holds a pattern that matches
nodes. If you apply templates to a node then the template will be used
on the node if the node matches the pattern. For example:

>  <xsl:template match="AAA/BBB/CCC[data_status = 'OK']">

This *matches* CCC elements whose parent is a BBB element and whose
grandparent is an AAA element, and that has a data_status child
element with a value of 'OK'. If you apply templates to a CCC element
that meets that description, then this is the template that will be
used to generate the result from it. Within the template, the current
node, the node you're processing, is a CCC element.

The select attribute of xsl:apply-templates and xsl:for-each holds a
path that selects nodes. The path is resolved relative to the current
node - the node that you're currently processing. So if within a
template that matches a CCC element you do:

>          <xsl:for-each select ="AAA">

then you create some output for each AAA element that's a child of the
CCC element. If there aren't any, you don't create any output.

Usually you should select the nodes that you want to process within
the select attribute of an xsl:apply-templates to apply templates to
them. So if you want to process AAA elements whose child BBB element's
child CCC element's data_status child element has a value of 'OK', and
you're currently on the DocRoot element parent of the AAA element, you
need to do:

  <xsl:apply-templates select="AAA[BBB/CCC/data_status = 'OK']" />

You are applying templates to AAA elements so you need a template that
matches AAA elements. A template that matches AAA elements will look
like:

<xsl:template match="AAA">
  ...
</xsl:template>

If you're familiar with CSS, you might find it helpful to think of
templates as rules like CSS rules. The match pattern holds the
selector for the rule, and the content of the template is what gets
done with elements of that type. It's just that in XSLT you can choose
which elements get templates applied to them whereas in CSS then
everything has rules applied to them.

So to create a table of information holding rows generated from AAA
elements whose child BBB element's child CCC element's data_status
child has a value of 'OK' you need to have a template that only gets
applied once to generate the table element. The template for the
DocRoot element is a good place for this:

<xsl:template match="DocRoot">
  <TABLE>
    <TR>
      <TD>
        <B>Table start stuff</B>
      </TD>
    </TR>
    <xsl:apply-templates select="AAA[BBB/CCC/data_status = 'OK']" />
  </TABLE>
</xsl:template>

Then you can have a template that matches AAA elements and generates
the rows of the table:

<xsl:template match="AAA">
  <TR>
    <TD><xsl:value-of select="BBB/detailed_bbb1"/></TD>
    <TD><xsl:value-of select="BBB/detailed_bbb2"/></TD>
    <TD><xsl:value-of select="DDD/detailed_ddd1"/></TD>
  </TR>
</xsl:template>

If you prefer, you can use xsl:for-each to iterate over the AAA
elements rather than applying templates to them, as follows:

<xsl:template match="DocRoot">
  <TABLE>
    <TR>
      <TD>
        <B>Table start stuff</B>
      </TD>
    </TR>
    <xsl:for-each select="AAA[BBB/CCC/data_status = 'OK']">
      <TR>
        <TD><xsl:value-of select="BBB/detailed_bbb1"/></TD>
        <TD><xsl:value-of select="BBB/detailed_bbb2"/></TD>
        <TD><xsl:value-of select="DDD/detailed_ddd1"/></TD>
      </TR>
    </xsl:for-each>
  </TABLE>
</xsl:template>

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 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]