xsl-list
[Top] [All Lists]

Re: Newline problems

2003-05-07 22:47:41
Vishwajit Pantvaidya wrote:
Thanks Mike, this to me seems like a novel way of doing it.

It's the preferred, template-driven, "push" way... I'm not trying to be
novel or clever; it's typically considered the "right" way to use XSLT.
Once you understand XSLT's processing model better, it makes much more
sense.

I guess it would 
be good to use this approach when there are very few elements from the src 
xml that are not needed in the output xml i.e. I do not have too many 
templates to ignore elements (just like you have here for BILL_TO_ADDRESS3).

Yes, but there are tricks you can use to compare to many values, if you
need to. 

<xsl:stylesheet ...  xmlns:data="urn:mydata">

<data:data>
  <data:x>BILL_TO_ADDRESS3</data:x>
  <data:x>IGNORE_THIS_TOO</data:x>
  <data:x>AND_THIS</data:x>
</data:data>

<xsl:variable name="mydata" select="document('')/xsl:stylesheet/data:data"/>

<xsl:template match="attribute">
  <xsl:if test="not(normalize-space(name)=$mydata/data:x)">
    ...
  </xsl:if>
</xsl:template>

Just an addition - I had to add an "!" before the DOCTYPE.

Ah, right.

  <!-- when processing a text node, generate a new text node
    using the normalized value of the original node -->
  <xsl:template match="text()">
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:template>


When does this overridden text template get called. We do not seem to have 
any templates that explicitly match text(). Does it get auto called when any 
text is encountered?

Here is where you need to understand the processing model better. XSLT is
declarative; you declare that a template is a good match for a certain class
of node. The XSLT processor starts processing at the root node, finds the best
matching template for that node, executes the instructions therein, and exits.

It is the presence of xsl:apply-templates or xsl:for-each instructions in the
template that causes more nodes to be selected for processing, and thus, in
the case of xsl:apply-templates, more match templates to be invoked.

There are built-in templates that match each kind of node. I pointed that out
here:


  <!-- don't forget that there is a built-in template that we're
     relying on to handle the atomicValue elements (and any others
     that we didn't provide explicit templates for): it just results
     in the processing of the element's children; nothing is
     generated. It looks like this:
      <xsl:template match="*">
        <xsl:apply-templates/>
      </xsl:template>
  -->

That is, this built-in template is being used to process the atomicValue
elements, because we don't have any other templates that are a better match.
Those atomicValue elements have text node children. When those are selected
for processing by the apply-templates instruction above, they end up being
processed by our template that has match="text()".

The built-in templates result in a recursive descension of the source tree,
avoiding attribute nodes, and when a text node is reached, it is copied to the
result tree. Generally any stylesheet you write is overriding the built-in
templates for certain nodes, but not necessarily all of them.

-Mike


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



<Prev in Thread] Current Thread [Next in Thread>