You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xalan.apache.org by "Martinez, Christian" <Ch...@bofasecurities.com> on 2006/01/18 14:55:56 UTC

RE: how to filter elements in XPath

One way I can think of is using xsl:when.  In the test case you might be
able to do something like

<xsl:variable name="myName" select="name(current())"/>
<xsl:choose>
	<xsl:when test="$myName != DDD | $myName != XXX">
		<!-- I guess here you would print out whatever -->
	</xsl:when>
</xsl:choose> 

This would filter out any unwanted elements.


Christian

-----Original Message-----
From: Enric Jaen [mailto:enric@nmg.upc.es] 
Sent: Wednesday, January 18, 2006 6:23 AM
To: xalan-j-users@xml.apache.org
Subject: how to filter elements in XPath

Hi,
Is there any way to filter the child elements of a given Xpath
expression? (without using multiple paths)

For example, having this:

<AAA>
  <BBB/>
  <CCC/>
  <DDD/>
</AAA>

I'd like to return AAA with only BBB and CCC elements, like this:

<AAA>
  <BBB/>
  <CCC/>
</AAA>


Regards,
-Enric


Re: how to filter elements in XPath

Posted by Enric Jaen <en...@nmg.upc.es>.
> "Filtering" in XPath is done using predicates, which are enclosed in
> "[]".  For example, I could filter "book" elements, selecting only those
> "book" elements with a "title" child element that has a particular value:
>
> //book[title = 'The book I'm looking for']
>
> > For example, if I wanted to select all the books , but I am only
> interested in its title and price, I could write something like (invented):
> > //book(title,price) >
>
> But if that's what you want, you're not selecting all the "book"
> elements.  Rather, you are selecting the "title" and "price" children of
> all "book" elements:
>
>      //book/title | //book/price
This would return
<title>..
<price>..
<title>..
<price>..
..

But what I mean is to select the books, but only returning the title and price:
<book>
  <title>..
  <price>..
</book>
<book>
  <title>..
  <price>..
</book>


But as you say this is a new tree.. Thank you.

-Enric

>
> >  But according your replies seems that XSLT should be used instead..
> >
>
> XPath 1.0 cannot construct nodes, so you can only use it to select nodes
> in the source tree.  If you need to construct a new tree, then you need
> XSLT.

>
> Dave
>
>


Re: how to filter elements in XPath

Posted by David Bertoni <db...@apache.org>.
Enric Jaen wrote:
> My question was rather if that kind of filter could be expressed with
> XPath itself, just as Xpath uses @ to filter elements by attributes
> (for example: //book[@lang] selects those books elements that have a
> lang attribute)
> 

XPath doesn't use "@" to "filter elements by attributes."  "@" is an 
abbreviation for the attribute axis, and is used for more general purposes:

http://www.w3.org/TR/xpath#axes

"Filtering" in XPath is done using predicates, which are enclosed in 
"[]".  For example, I could filter "book" elements, selecting only those 
"book" elements with a "title" child element that has a particular value:

//book[title = 'The book I'm looking for']

> For example, if I wanted to select all the books , but I am only
interested in its title and price, I could write something like (invented):
> //book(title,price) >

But if that's what you want, you're not selecting all the "book" 
elements.  Rather, you are selecting the "title" and "price" children of 
all "book" elements:

     //book/title | //book/price

>  But according your replies seems that XSLT should be used instead..
> 

XPath 1.0 cannot construct nodes, so you can only use it to select nodes 
in the source tree.  If you need to construct a new tree, then you need 
XSLT.

Dave

Re: how to filter elements in XPath

Posted by Joseph Kesselman <ke...@us.ibm.com>.
>Joseph, I think you meant to write something in place of that second
>"XPath" in your first para, no? (XSLT?)

Yes, I meant XSLT. Sorry. "Engage mind before putting fingers in gear."

And yes, XQuery (if you have it available) is another option. In fact, XSLT
2.0 and XQuery are in a very real sense "two different syntaxes for the
same language"; they're written differently and they do have some
divergence in features, but the underlying structure is close enough that
it was actually possible to generate both formal specifications from a
single source document. (I don't know whether that's still how they're
being maintained, but it was a good technique for ensuring that the two
stayed in synch with each other.)


______________________________________
Joe Kesselman, IBM Next-Generation Web Technologies: XML, XSL and more.
"The world changed profoundly and unpredictably the day Tim Berners Lee
got bitten by a radioactive spider." -- Rafe Culpin, in r.m.filk


Re: how to filter elements in XPath

Posted by "Eric J. Schwarzenbach" <Er...@wrycan.com>.
Joseph, I think you meant to write something in place of that second
"XPath" in your first para, no? (XSLT?)

I believe you can do this sort of thing with XQuery, also.

Joseph Kesselman wrote:
> Remember that XPath just selects a set of nodes. If you want to construct a
> new tree based on those nodes, you need something like XPath -- or some
> hand-coded equivalent -- to do that construction.
>
> Selecting only the book and its title and price is easy:
>       book | book/title | book/price
> is one of several ways to express that. But that shows you the individual
> nodes; it doesn't display the relationships between them.
>
> If what you're looking for is a filtered view of an in-memory document
> without recopying, you might want to investigate the DOM Level 2 Traversal
> chapter. TreeWalker's intended to give you exactly that, though you have to
> learn how to work with it.
>
> ______________________________________
> Joe Kesselman, IBM Next-Generation Web Technologies: XML, XSL and more.
> "The world changed profoundly and unpredictably the day Tim Berners Lee
> got bitten by a radioactive spider." -- Rafe Culpin, in r.m.filk
>
>
>   

RE: how to filter elements in XPath

Posted by Joseph Kesselman <ke...@us.ibm.com>.
Remember that XPath just selects a set of nodes. If you want to construct a
new tree based on those nodes, you need something like XPath -- or some
hand-coded equivalent -- to do that construction.

Selecting only the book and its title and price is easy:
      book | book/title | book/price
is one of several ways to express that. But that shows you the individual
nodes; it doesn't display the relationships between them.

If what you're looking for is a filtered view of an in-memory document
without recopying, you might want to investigate the DOM Level 2 Traversal
chapter. TreeWalker's intended to give you exactly that, though you have to
learn how to work with it.

______________________________________
Joe Kesselman, IBM Next-Generation Web Technologies: XML, XSL and more.
"The world changed profoundly and unpredictably the day Tim Berners Lee
got bitten by a radioactive spider." -- Rafe Culpin, in r.m.filk


RE: how to filter elements in XPath

Posted by Enric Jaen <en...@nmg.upc.es>.
 My question was rather if that kind of filter could be expressed with XPath itself, just as Xpath uses @ to filter elements by attributes (for example: //book[@lang] selects those books elements that have a lang attribute)

 For example, if I wanted to select all the books , but I am only interested in its title and price, I could   write something like (invented):
  //book(title,price)

 But according your replies seems that XSLT should be used instead..

 Regards,
 -Enric


On Wed, 18 Jan 2006, Florent Georges wrote:

> "Martinez, Christian" wrote:
>
> > <xsl:variable name="myName" select="name(current())"/>
> > <xsl:choose>
> > 	<xsl:when test="$myName != DDD | $myName != XXX">
> > 		<!-- I guess here you would print out whatever -->
> > 	</xsl:when>
> > </xsl:choose>
>
>   If you want that (I doubt it is what the OP want), use this instead:
>
>     <xsl:if test="not(self::DDD|self::XXX)">
>       ...
>     </xsl:if>
>
>   BTW, 'name()' (better here 'local-name()') returns a string, so:
>
>     test="$myName != DDD | $myName != XXX"
>
> has to be rewritten:
>
>     test="$myName!='DDD' and $myName!='XXX'"
>
> --drkm
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> ___________________________________________________________________________
> Nouveau : t�l�phonez moins cher avec Yahoo! Messenger ! D�couvez les tarifs exceptionnels pour appeler la France et l'international.
> T�l�chargez sur http://fr.messenger.yahoo.com
>
>


RE: how to filter elements in XPath

Posted by Florent Georges <da...@yahoo.fr>.
"Martinez, Christian" wrote:

> <xsl:variable name="myName" select="name(current())"/>
> <xsl:choose>
> 	<xsl:when test="$myName != DDD | $myName != XXX">
> 		<!-- I guess here you would print out whatever -->
> 	</xsl:when>
> </xsl:choose> 

  If you want that (I doubt it is what the OP want), use this instead:

    <xsl:if test="not(self::DDD|self::XXX)">
      ...
    </xsl:if>

  BTW, 'name()' (better here 'local-name()') returns a string, so:

    test="$myName != DDD | $myName != XXX"

has to be rewritten:

    test="$myName!='DDD' and $myName!='XXX'"

--drkm


















	

	
		
___________________________________________________________________________ 
Nouveau : téléphonez moins cher avec Yahoo! Messenger ! Découvez les tarifs exceptionnels pour appeler la France et l'international.
Téléchargez sur http://fr.messenger.yahoo.com