Preserving text position but transforming sub elements.

  • Thread starter Matthew Rees-George
  • Start date
M

Matthew Rees-George

I want this example xml:-
<xxx>text before <yyy att="value"/> text in the middle <zzz>ignored
but transformed</zzz> text after</xxx>

To be transformed to this:-
text before value text in the middle 'found a zzz' text after

I.e. the text positions must be preserved, but the element(s) must be
transformed.

I could not find similar problems or solutions on the web or
newsgroups, but I have this solution, which I really, really do not
like:-

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:eek:utput method="text" indent="yes" encoding="utf-8"/>

<xsl:template match="/">
<xsl:apply-templates select="xxx"/>
</xsl:template>

<xsl:template match="xxx">
<xsl:for-each select="node()">
<xsl:choose>
<xsl:when test="name(.)='yyy'"><xsl:value-of
select="@att"/></xsl:when>
<xsl:when test="name(.)='zzz'">'found a zzz'</xsl:when>
<xsl:eek:therwise><xsl:copy/></xsl:eek:therwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

There must be a more obvious solution? Anyone?
 
A

arnold m. slotnik

(e-mail address removed) (Matthew Rees-George) wrote in
I could not find similar problems or solutions on the web or
newsgroups, but I have this solution, which I really, really do
not like:-

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:eek:utput method="text" indent="yes" encoding="utf-8"/>

<xsl:template match="/">
<xsl:apply-templates select="xxx"/>
</xsl:template>

<xsl:template match="xxx">
<xsl:for-each select="node()">
<xsl:choose>
<xsl:when test="name(.)='yyy'"><xsl:value-of
select="@att"/></xsl:when>
<xsl:when test="name(.)='zzz'">'found a
zzz'</xsl:when>
<xsl:eek:therwise><xsl:copy/></xsl:eek:therwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

There must be a more obvious solution? Anyone?

Repeat after me: "Simpler is better".

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:eek:utput method="text" indent="no" encoding="utf-8"/>

<!--First, match the xxx element and process its content -->

<xsl:template match="xxx">
<xsl:apply-templates/>
</xsl:template>

<!--Now let's deal with yyy -->

<xsl:template match="yyy">
<xsl:value-of select="@att"/>
</xsl:template>

<!--Finally, take care of the zzz element -->

<xsl:template match="zzz">
<xsl:text> 'found a zzz' </xsl:text>
</xsl:template>

</xsl:stylesheet>
 
C

Christopher Boomer

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput method="text" indent="no" encoding="utf-8"/>

<!--First, match the xxx element and process its content -->
<xsl:template match="xxx">
<xsl:apply-templates/>
</xsl:template>

<!--Now let's deal with yyy -->
<xsl:template match="yyy">
<xsl:value-of select="@att"/>
</xsl:template>

<!--Finally, take care of the zzz element -->
<xsl:template match="zzz">
<xsl:text> 'found a zzz' </xsl:text>
</xsl:template>

</xsl:stylesheet>

When you say it like that, it almost makes sense. But do you really think
that people are going to enter their expletives in zzz-tags? ;-)

I think after two months that XSLT is starting to sink into my brain. I've
had trouble convincing myself that templates were really function
definitions and that apply-templates was really a "run-source" command. I
guess you don't expect the program flow to be controlled by your input
parameter.

Strange world, strange syntax. Thanks both for the revelation.

One question: is it important to deal with xxx first? I suspect not, and
I'm used to defining functions before I attempt to call them, so I would
probably graduate to doing that last.
 
A

arnold m. slotnik

One question: is it important to deal with xxx first? I suspect
not, and I'm used to defining functions before I attempt to call
them, so I would probably graduate to doing that last.

No, the order of the templates in the stylesheet in this case don't
matter.
 
M

Matthew Rees-George

Thanks, I knew it was blatently obvious ~ I just couldn't see the wood
for the trees (common problem in XSLT?). I forgot that you could
apply-templates without a select ~ and I have always selected. Learnt
my lesson.
 
S

Steven Dilley

Christopher Boomer said:
I've had trouble convincing myself that templates were really function
definitions and that apply-templates was really a "run-source" command.
I guess you don't expect the program flow to be controlled by your input
parameter.

It is best to throw out all concepts of "program flow", "functions", etc.
This is more like CSS: a set of patterns and corresponding outcomes.
(Or like awk or prolog).
The "input parameter" is what matches the pattern and activates the rule.

It is like saying "Put all nails in the blue drawer and all screws in the
green drawer". There is no assumption that the mixture of nails/screws
will be in any order, or that the rules will be handled sequentially.

Of course, selectively applying particular templates to a particular
sub-tree can make it look like a program, and the 'if' and 'for-each'
tags are very program-like. However, you can do most simple xsl
without either selecting templates or using batch-processing nodes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top