Re: XPath Search
Brought to you by:
bs_php,
nigelswinson
|
From: Nigel S. <nig...@us...> - 2006-02-11 02:03:16
|
Returns a list of features:
//feature[contains(.,'search string')]
=20
Returns a list of components
//feature[contains(.,'search string')]/..
The trailing /.. is no accident. It filters duplicates too
Nigel
----- Original Message -----=20
From: Tod McIntyre=20
To: Nigel Swinson=20
Cc: php...@li...=20
Sent: Friday, February 10, 2006 8:07 PM
Subject: Re: XPath Search
excellent... very thorough! Now, my only question is... once I =
have a list of all the features that match a particular phrase, along =
with keywords etc. I want to then get the component that that feature =
belongs to. I'm not exactly sure how to get the parent. I tried some =
of XPath the axis fcn's such as "parent::feature", to no avail. I'm not =
even really sure what the exact syntax is in order to get this to work =
anyway. Can someone tell me how to get the component element of the =
feature that matches. Then all I need to do is eliminate duplicates and =
I'm set!
Thanks again for all the help,
Brad
On 2/7/06, Nigel Swinson <nig...@us...> wrote:
I've narrowed the problem down. When I search through keywords in =
the xml file (each component has one keyword tag with multiple words) it =
works fine using:
=
$components=3D$xPath->match("//component[contains(keyword,'string')]");
but when I search through features (each component has multiple =
features) using:
=
$components=3D$xPath->match("//component[contains(feature,'string')]");
I get an empty array.
Do I have to do something different if there are multiple tags such =
as feature?
Worked it out. When you search for =
//component[contains(feature,'string')], then it first of all evaluates =
//component to get a list of context nodes, which will be something =
like:
XPathSet:Array
(
[0] =3D> /product[1]/component[1]
[1] =3D> /product[1]/component[6]
)
Then it filters the list based on the predicate, which is the =
contains(feature,'string') bit. But to do this, it needs to evaluate =
the "feature" for each of the context nodes. But for the first context =
node this returns something like:
Array
(
[0] =3D> /product[1]/component[1]/feature[1]
[1] =3D> /product[1]/component[1]/feature[2]
[2] =3D> /product[1]/component[1]/feature[3]
[3] =3D> /product[1]/component[1]/feature[4]
)
So the LHS is an array, and the RHS is a string. According to =
http://www.w3.org/TR/xpath#function-string, the contains function will =
convert the LHS to a string by "A node-set is converted to a string by =
returning the string-value of the node in the node-set that is first in =
document order . If the node-set is empty, an empty string is =
returned.". And thus it will take the text part of =
/product[1]/component[1]/feature[1], and ignore the rest.
This explains why it works for the keyword, as you only have one =
keyword.
Instead of finding all components, and then filtering the list, =
instead we should find all features, and then go back up a level to get =
their owning components. So we do:
//feature[contains(.,'search string')]/..
Nigel
|