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

Re: [xsl] Building select-clause dynamically with parameters


Subject: Re: [xsl] Building select-clause dynamically with parameters
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Wed, 11 Dec 2002 00:04:28 -0800 (PST)

Hi Marko,

The problem I still have with your stylesheet is that it does not work
(always) correctly. Also, it is probably not extremely efficient.

> The xml file contains 2 books with some chapters and sections,
> the text to be used as $query is hard coded in the xsl (in this case
> 'test'). The result is what I expect: a list of sections which
contain
> the word (highlighted in html), and the list should contain all
parent
> sections and chapters of this sections.

It works with ***this** xml file.  However, replace your second "book"
element with:

<book id="book2">
<title>Book 2</title>
<chapter id="chap21">
   <title>Chapter 1 of B2</title>
   <section id="sec211">
      <title>Section 1 of C1 of B2</title>
      <para>some text here</para>
      <section id="sec2111">
         <title>Subsection 1 of S1 of C1 of B2</title>
         <para>nothing</para>
      </section>
      <section id="sec2112">
         <title>Subsection 2 of S1 of C1 of B2</title><para>test</para>
      </section>
   </section>
   <section id="sec221">
      <title>Section 2 of C1 of B2</title>
      <para>something else</para>
   </section>
</chapter>
</book>

and define $searchtext as follows:
  
   <xsl:variable name="searchtext" select="'B2test'"/>


The result of applying the transformation (as displayed by the browser)
is:

"Query: B2test

Book 1

Book 2

   1  Chapter 1 of B2
   1.1  Section 1 of C1 of B2
   1.1.2  Subsection 2 of S1 of C1 of B2"



Now, the word "B2test" is not contained in any single text node.

I think that this is a wrong result.

Even if we define the search in such a way so that a result as the
above is considered OK, this expression (contained 4 times in your
code:

contains(descendant-or-self::*,$searchtext)

is equivalent to the much more obvious and not misleading:

contains(., $searchtext)

and the former would be performed much more inefficiently.

> The question for me is how to pass an unknown number of words to
> the stylesheet and how to build the select-clause dynamically. For
now
> it is limited to one word, but I need something like "not(word1) and
word2"
> or "word1 or (word2 and word3)".

I don't think this code should be further complicated, before
correcting its current problem.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL




"Marko Petersen" <lg002237@xxxxxxxxxxxxxxxx> wrote in message
news:5.1.1.6.0.20021211021133.00b9f308@xxxxxxxxxxxxxxxxxxx
> Hi,
>
> to explain it in more detail I uploaded an example xml and xsl
> (I don't want to post it all to the list) with result html to a
server:
> http://digipub.fhnon.de/~mpetersen/xsl/
>
> The xml file contains 2 books with some chapters and sections,
> the text to be used as $query is hard coded in the xsl (in this case
> 'test'). The result is what I expect: a list of sections which
contain
> the word (highlighted in html), and the list should contain all
parent
> sections and chapters of this sections.
>
> The question for me is how to pass an unknown number of words to
> the stylesheet and how to build the select-clause dynamically. For
now
> it is limited to one word, but I need something like "not(word1) and
word2"
> or "word1 or (word2 and word3)".
>
> Thanks for your help and greetings,
>
> Marko
>
> At 13:07 10.12.2002 -0800, you wrote:
> >Probably you think that the following applies the appropriate
templates
> >to ***all*** of the set of the a "chapter" node and its descendents,
> >the string value of which contains the value of $query?
> >
> > >     <xsl:template match="/">
> > >       <xsl:apply-templates
> > > select="chapter[contains(descendant-or-self::*,$query)]"/>
> > >     </xsl:template>
> >
> >This is wrong. The above code will apply a template only to every
> >"chapter" node, the text of which contains that of $query -- not to
any
> >descendent of a "chapter", even if the descendent contains the text
of
> >$query.
> >
> >At first it may seem that a "chapter" will be selected if one of its
> >descendents contains $query -- this may not be the case. A "chapter"
> >may be selected even if none of its descendents (including its own
> >children text nodes) contains $query. This will be the case, when
> >$query is "made up" by the concatenation of the text of several
> >descendents.
> >
> >It seems to me that the code above does not express at all what you
> >wanted.
> >
> >
> >=====
> >Cheers,
> >
> >Dimitre Novatchev.
> >http://fxsl.sourceforge.net/ -- the home of FXSL
> >
> >
> >
> >
> >"Marko Petersen" <lg002237@xxxxxxxxxxxxxxxx> wrote in message
> >news:5.1.1.6.0.20021210194812.00bb66f0@xxxxxxxxxxxxxxxxxxx
> > > Hi,
> > >
> > > I would like to pass some words into my XSL file which should be
used
> > > to build an XPath query in xsl:apply-templates. For an example,
the
> >following
> > > works, but only for one word:
> > >
> > >     <?xml version="1.0" encoding="ISO-8859-1"?>
> > >     <xsl:stylesheet version="1.0"
> > >      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> > >
> > >     <xsl:param name="query"/>
> > >
> > >     <xsl:template match="/">
> > >       <xsl:apply-templates
> > > select="chapter[contains(descendant-or-self::*,$query)]"/>
> > >     </xsl:template>
> > >
> > >     <xsl:template match="chapter | section">
> > >       <table>
> > >         <tr>
> > >           <td>&#160;</td>
> > >           <td>Found <xsl:value-of select="title"/>
> > >             <xsl:apply-templates
> > > select="section[contains(descendant-or-self::*, $query)]"/>
> > >           </td>
> > >         </tr>
> > >       </table>
> > >     </xsl:template>
> > >
> > >     </xsl:stylesheet>
> > >
> > > I don't know how many words will be passed into the XSL file,
this
> >should
> > > be flexible.
> > > For example, If $query has the value "word1 word2", the only
chapters
> >and
> > > sections that
> > > should be selected by apply-templates are those which contain
word1
> >or
> > > word2, I think
> > > in this case need I something like:
> > >
> > >       <xsl:apply-templates
> > > select="chapter[contains(descendant-or-self::*,'word1') or
> > >
> >contains(descendant-or-self::*,'word2')]"/>
> > >
> > > I tried to pass the whole string used by "select" as parameter,
but
> >it does
> > > not work.
> > >
> > > Another thing is that I also have words that should be excluded
and
> >that I
> > > would like
> > > to pass a value into the XSL file that should define if it is an
AND
> >or an
> > > OR query to
> > > build something like:
> > >
> > >       <xsl:apply-templates
> > > select="chapter[contains(descendant-or-self::*,'word1') and
> > >
> >contains(descendant-or-self::*,'word2')
> > > and
> > >
> >not(contains(descendant-or-self::*,'word3'))]"/>
> > >
> > > Has anyone an idea how to do something like this? Or is it a
better
> > > solution to do this
> > > with Java DOM?
> > >
> > > Thanks for help and greetings,
> > >
> > > Marko


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

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



Current Thread
Keywords