[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Can't get output from xml -> text transformation


Subject: Re: [xsl] Can't get output from xml -> text transformation
From: "M. David Peterson" <m.david@xxxxxxxxxx>
Date: Wed, 11 Aug 2004 15:50:26 -0600

BTW... nice usage of the spec to back up your comments... Its so much easier to follow someones thought process when they point out exactly what they are referring too...

Nice :)

Josh Canfield wrote:

Hmm... actually after closing the featuredGame element the provided
XSL does work, although there was a lot of unwanted space.

The built-in template rules allow for processing nodes deep within the
tree without having to account for every parent node in the tree. It's
only when you catch a node in a template match that you have to worrry
about deeper nodes getting processed.

It seems like what you are describing is the behavior of xsl:value-of,
which is often confused for xsl:copy-of


It seems that what you are expecting to happen is for every node (every child of
a child of a child etc...) to be processed according to document order and when
there is not matching template it will simply move to the next child or
grandchild until it finds a match.


This is exactly what happens... except that there is always a matching
template because of the built-in template rules...

See http://www.w3.org/TR/xslt#built-in-rule

Josh

On Wed, 11 Aug 2004 12:25:06 -0600, M. David Peterson
<m.david@xxxxxxxxxx> wrote:

Hi Todd,

Understanding what nodes are being processed and matched to a template will help
in your understanding of whats happening.  <xsl:apply-templates /> is the same
thing as <xsl:apply-templates select="*"/> which will select all the children of
the current context (root) and seek out a template to match them to (in your
case there are no matching templates to the children of context - one node by
the name of "allGamesDownloadable" - and as such the "value" of each child node
is simply sent to the output "as is" until there are no more children left to
process.  The "blank" lines you are seeing are most likely the newline
characters that exist as child "text" nodes of "allGamesDownloadable" in your
source XML.

It seems that what you are expecting to happen is for every node (every child of
a child of a child etc...) to be processed according to document order and when
there is not matching template it will simply move to the next child or
grandchild until it finds a match.  While this is in no way an uncommon mistake
- in fact its a VERY common mistake - it is fundamentally flawed from an XSLT
template matching perspective and as such will not provide you the results you
are looking for.  If you try to think of it from the perspective that to gain
access to the children of the current context node you must begin the recursive
nature of apply-templates when the desired children are in context you will find
yourself catching your errors quite easily... for example, the following will
select the children of the root node, find the best matching template, process
it accordingly, and then begin the recursive process on the children of the
current context node ("allGamesDownloadable") by once again calling
apply-templates at a time when the children are in context.  Because we are
using "*" for our match value the same template will match the children
currently being processed which means any children of these children will be
recursively processed and matched to the same template and this process will
continue until every node in the source document has gone through "the ringer"
so to speak...

so this....

<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

<xsl:template match="/">
<xsl:text>
GAMEID,GAMENAME
</xsl:text>
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="*">
<xsl:value-of select="@gameId"/>,
<xsl:apply-templates/>
</xsl:template>

Will output the value of @gameId for every node that is processed by this
template that has an attribute gameId.

While this particular case will not give you the CSV output you are in desire of
this should give you just enough information to help move you in the right
direction...

Best of luck to you!

<M:D/>



Todd Alexander wrote:

I have an xsl I'm running through xalan against an xml file, with the
output going to a csv file. My problem is that I get the output
expected for the first template rule in the csv file but I canot get
anything output for the second. I'm getting blank spaces for each
node I'm expecting to hit for the second rule, so I know I'm getting
there, but no matter what I put inside the rule (xsl:text , xsl:value-
of etc) I cannot get any text of any kind.

The source xml file looks like:

<?xml version="1.0"?>
<allGamesDownloadable>
<featuredGameList title="Featured Downloads">
<featuredGame featuredHeadline="blah blah blah"
gameId="gameOne">
</featuredGameList>
<gameGroupList>
<gameGroup title="Action Games">
<gameItem gameID="gameOne"/>
<gameItem gameID="gameTwo"/>
</gameGroup>
<gameGroup title="Arcade">
<gameItem gameID="gameThree"/>
<gameItem gameID="gameFour"/>
</gameGroup>
</gameGroupList>
</allGamesDownloadable>

The XSL in question is:
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

<xsl:template match="/">
<xsl:text>
GAMEID,GAMENAME
</xsl:text>
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="gameItem">
<!-- for debugging -->
<xsl:text>cracker</xsl:text>
</xsl:template>

</xsl:stylesheet>

What I get output is:

GAMEID,GAMENAME

{then the expected numner of lines with varying numbers of spaces}



Thanks,
Todd Alexander
heeznow@xxxxxxx


Current Thread
Keywords