XPath equivalent to XSL contains() function

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

XPath equivalent to XSL contains() function

StephR
Just discovered something which screws up about everything I did ;) :

XSL contains() function take a list of strings as first argument, then compares it to a string in the 2nd argument.

XPath only accepts one string as first & 2nd argument :(

Do you have any idea how I could implement the following :

<p:choose ... >
    <p:when test="contains('hello orbeon help me', 'help')>

Thanks


--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: XPath equivalent to XSL contains() function

fl.schmitt
Hi Stephane,

> XSL contains() function take a list of strings as first argument, then
> compares it to a string in the 2nd argument.
>
> XPath only accepts one string as first & 2nd argument :(
>
> Do you have any idea how I could implement the following :
>
> <p:choose ... >
>     <p:when test="contains('hello orbeon help me', 'help')>

Maybe you could concat() the different strings in a first step to get a
single string, and then apply the contains() function. I'm not sure
whether the XSL contains() function returns different results depending
on which string matched the pattern; if it doesn't, there should be no
difference between matching against multiple strings or against a
concatenation of those strings (i think).

HTH
florian




--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: XPath equivalent to XSL contains() function

StephR
Hi Florian,

I thought about it but I can see how it will help me. Here is the input :

allData:

<root>
    [...]
    <apps>budget news wps</apps>
    [...]


<p:choose href="#allData">
     <p:when test="not(contains(/root/apps, tokenize(/root/request/request-path, '/')[last()]))">

For me, /root/apps is already one string, no ? And if not, how can I concat this ????




Florian Schmitt a écrit :
Hi Stephane,

XSL contains() function take a list of strings as first argument, then compares it to a string in the 2nd argument.

XPath only accepts one string as first & 2nd argument :(

Do you have any idea how I could implement the following :

<p:choose ... >
    <p:when test="contains('hello orbeon help me', 'help')>

Maybe you could concat() the different strings in a first step to get a single string, and then apply the contains() function. I'm not sure whether the XSL contains() function returns different results depending on which string matched the pattern; if it doesn't, there should be no difference between matching against multiple strings or against a concatenation of those strings (i think).

HTH
florian




--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: XPath equivalent to XSL contains() function

fl.schmitt
Hi Stephane,

> I thought about it but I can see how it will help me. Here is the input :
>
> allData:
>
> <root>
>     [...]
>     <apps>budget news wps</apps>
>     [...]
>
>
> <p:choose href="#allData">
>      <p:when test="not(contains(/root/apps,
> tokenize(/root/request/request-path, '/')[last()]))">
>
> For me, /root/apps is already one string, no ? And if not, how can I
> concat this ????
sorry, i misunderstood your question. concatenation doesn't make sense
in this context, you're right. But then i'm not sure what's exactly the
problem. If i take your example from your first message:

contains('hello orbeon help me', 'help')

and paste this into the XPath Sandbox, i get the correct result 'true'.
If the pattern should be more complex then a single string, you could
use matches(text, pattern). An example for the XPath sandbox:

//employee[matches(@firstname, 'John|Bruce')]

gives the two employees with the firstname John or Bruce. That's
something that can't be achieved with contains, i think.

florian




--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: XPath equivalent to XSL contains() function

StephR
I found the problem :

actually, my input is the following :

<root>
    <apps>
       <app>budget</app>
       <app>news</app>
       [...]
    </apps>
[...]

In XSL, this will work : contains(/root/apps/apps, tokenize(/root/request/request-path, '/')[last()])"> but not in XPath.

I will have to modify the data input... even though it's too bad I can't do easily with XPath.

Thanks for you help !

Steph



Florian Schmitt a écrit :
Hi Stephane,

I thought about it but I can see how it will help me. Here is the input :

allData:

<root>
    [...]
    <apps>budget news wps</apps>
    [...]


<p:choose href="#allData">
     <p:when test="not(contains(/root/apps, tokenize(/root/request/request-path, '/')[last()]))">

For me, /root/apps is already one string, no ? And if not, how can I concat this ????

sorry, i misunderstood your question. concatenation doesn't make sense in this context, you're right. But then i'm not sure what's exactly the problem. If i take your example from your first message:

contains('hello orbeon help me', 'help')

and paste this into the XPath Sandbox, i get the correct result 'true'. If the pattern should be more complex then a single string, you could use matches(text, pattern). An example for the XPath sandbox:

//employee[matches(@firstname, 'John|Bruce')]

gives the two employees with the firstname John or Bruce. That's something that can't be achieved with contains, i think.

florian




--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: XPath equivalent to XSL contains() function

fl.schmitt
Hi Stephane,

> actually, my input is the following :
>
> <root>
>     <apps>
>        <app>budget</app>
>        <app>news</app>
>        [...]
>     </apps>
> [...]
>
> In XSL, this will work : contains(/root/apps/apps,
                                               ^^^^^

i think it's a problem with your XPath. The element or nodeset
/root/apps/apps doesn't exist, it must be /root/apps. The following
works in the XPath Sandbox

Input:

<root>
     <apps>
        <app>budget</app>
        <app>news</app>
        <app>bork</app>
     </apps>
     <request>
       <request-path>foo/bla/news</request-path>
     </request>
</root>

XPath:

contains(/root/apps,  tokenize(/root/request/request-path, '/')[last()])

Output: 'true'

florian



--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: XPath equivalent to XSL contains() function

StephR
I'm sorry, I didn't read myself after writing :(

I meant /root/apps/app ... but you are right it does work but I don't understand:

in XSL : I have to write the following : contains(/root/apps/app, 'news') <!-- root/apps/app will return "bugdet news ..." -->
in XPath : I have to write : contains(/root/apps, 'news') <!-- if I write /root/apps/app, I will have the following error :

"A sequence of more than one item is not allowed as the first argument of contains() ("budget", "news")" ... -->

Pretty strange no ? Any thanks again Florian for your time...




Florian Schmitt a écrit :
Hi Stephane,

actually, my input is the following :

<root>
    <apps>
       <app>budget</app>
       <app>news</app>
       [...]
    </apps>
[...]

In XSL, this will work : contains(/root/apps/apps,
                                              ^^^^^

i think it's a problem with your XPath. The element or nodeset /root/apps/apps doesn't exist, it must be /root/apps. The following works in the XPath Sandbox

Input:

<root>
    <apps>
       <app>budget</app>
       <app>news</app>
       <app>bork</app>
    </apps>
    <request>
      <request-path>foo/bla/news</request-path>
    </request>
</root>

XPath:

contains(/root/apps,  tokenize(/root/request/request-path, '/')[last()])

Output: 'true'

florian



--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: XPath equivalent to XSL contains() function

Erik Bruchez
Administrator
Do you use XSLT 1.0?

Unless I am mistaken (always possible), this is a known difference  
between XSLT 1.0 and XPath 2.0 (therefore XSLT 2.0), which is that in  
1.0, passing a node-set where a single string is expected  
automatically uses the first node of the node-set, while in XPath 2.0  
this causes a dynamic error.

So try writing /root/apps/app[1] instead. If you wanted to check on  
all the "app" elements, then I don't think this does what you expect  
with XPath 1.0 either. But you could write something like this:

   sum(for $app in/root/apps/app return if contains($app, 'news') then  
1 else 0) > 0

-Erik

On Dec 15, 2007, at 1:48 AM, Stephane Ruchet wrote:

> I'm sorry, I didn't read myself after writing :(
>
> I meant /root/apps/app ... but you are right it does work but I  
> don't understand:
>
> in XSL : I have to write the following : contains(/root/apps/app,  
> 'news') <!-- root/apps/app will return "bugdet news ..." -->
> in XPath : I have to write : contains(/root/apps, 'news') <!-- if I  
> write /root/apps/app, I will have the following error :
>
> "A sequence of more than one item is not allowed as the first  
> argument of contains() ("budget", "news")" ... -->
>
> Pretty strange no ? Any thanks again Florian for your time...
>
>
>
> Florian Schmitt a écrit :
>>
>> Hi Stephane,
>>
>>> actually, my input is the following :
>>>
>>> <root>
>>>     <apps>
>>>        <app>budget</app>
>>>        <app>news</app>
>>>        [...]
>>>     </apps>
>>> [...]
>>>
>>> In XSL, this will work : contains(/root/apps/apps,
>>                                               ^^^^^
>>
>> i think it's a problem with your XPath. The element or nodeset /
>> root/apps/apps doesn't exist, it must be /root/apps. The following  
>> works in the XPath Sandbox
>>
>> Input:
>>
>> <root>
>>     <apps>
>>        <app>budget</app>
>>        <app>news</app>
>>        <app>bork</app>
>>     </apps>
>>     <request>
>>       <request-path>foo/bla/news</request-path>
>>     </request>
>> </root>
>>
>> XPath:
>>
>> contains(/root/apps,  tokenize(/root/request/request-path, '/')
>> [last()])
>>
>> Output: 'true'
>>
>> florian
>>
>
> --
> You receive this message as a subscriber of the [hidden email]  
> mailing list.
> To unsubscribe: mailto:[hidden email]
> For general help: mailto:[hidden email]?subject=help
> OW2 mailing lists service home page: http://www.ow2.org/wws
--
Orbeon Forms - Web Forms for the Enterprise Done the Right Way
http://www.orbeon.com/



--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws