Discussion:
[xquery-talk] xpath1 text node contains attribute, equivalent in xpath2
e-letter
2013-12-27 09:20:22 UTC
Permalink
Readers,

For an xml file:

...
<book
category="WEB"
<title
lang="en"
Learning XML
</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
...

An xquery file was created and processed using jedit xml plugins:

<html>
<body>
<p>
{
let $x := fn:doc("xmldatabasefile.xml")/bookstore/book/title[contains(text(),'XML')]/parent::*
return $x
}
</p>
</body>
</html>

Xpath1 specification § 4.2 string functions
(http://www.w3.org/TR/xpath/#section-String-Functions) describes a
"contains" function, but this was not found in xpath2; what is the
equivalent function in xpath2 please?

The resultant output:

<html>
<body>
<p>
<book category="WEB">

<title lang="en">
Learning XML

</title>

<author>Erik T. Ray</author>

<year>2003</year>

<price>39.95</price>

</book>
</p>
</body>
</html>

Is it possible to remove the xml elements from the output file?

An alternative xquery was attempted:

...<p>
{
let $x := fn:doc("xmldatabasefile.xml")/bookstore/book/title/text()
return $x
}
</p>...

Resultant output:

...<p>
Everyday Italian

Harry Potter

XQuery Kick Start

Learning XML

</p>...


Is it possible to select a specific title text with this xquery syntax?
Liam R E Quin
2013-12-27 09:30:03 UTC
Permalink
Post by e-letter
Xpath1 specification § 4.2 string functions
(http://www.w3.org/TR/xpath/#section-String-Functions) describes a
"contains" function, but this was not found in xpath2;
Better to use the XPath 2 Functions and Operators spec, which does
indeed list fn:contains().

In XQuery you might need to call it fn:contains() rather than
contains(), depending on options.
Post by e-letter
Is it possible to remove the xml elements from the output file?
Change return $x to return $x/text() maybe
Post by e-letter
...<p>
{
let $x := fn:doc("xmldatabasefile.xml")/bookstore/book/title/text()
return $x
}
</p>...
Is it possible to select a specific title text with this xquery syntax?
Yes. E.g. ......bookstore/book/title[fn:contains(., 'Learning XML')]

Liam
--
Liam Quin - XML Activity Lead, W3C, http://www.w3.org/People/Quin/
Pictures from old books: http://fromoldbooks.org/
Ankh: irc.sorcery.net irc.gnome.org freenode/#xml
e-letter
2013-12-27 12:03:35 UTC
Permalink
Post by Liam R E Quin
Post by e-letter
Xpath1 specification § 4.2 string functions
(http://www.w3.org/TR/xpath/#section-String-Functions) describes a
"contains" function, but this was not found in xpath2;
Better to use the XPath 2 Functions and Operators spec, which does
indeed list fn:contains().
{
let $x := fn:doc("xmldatabasefile.xml")/bookstore/book/title[fn:contains(.,'Learning
XML')]/parent::*
return $x
}

returns:

...<p>
<book category="WEB">

<title lang="en">
Learning XML

</title>

<author>Erik T. Ray</author>

<year>2003</year>

<price>39.95</price>

</book>
</p>...

Why is the full stop applied before the comma, because this is not
specified as an option in the specification about 'fn:contains'?
Post by Liam R E Quin
Post by e-letter
Is it possible to remove the xml elements from the output file?
Change return $x to return $x/text() maybe
Not quite, returns:

...<p>





</p>...


if 'return' is changed to 'return $x/element()', the result is as
'return $x', but interestingly a removal of new line white space.
Misztur, Chris
2013-12-27 16:02:07 UTC
Permalink
The period '.' in contains() means that you are passing the current sequence item (aka context) into the contains() function.
Imagine that query [1] is actually doing a for-each loop on each <title/> and the predicate in square brackets is applying a 'where' statement on each iteration. You can also rewrite query [1] as query [3].

Your other query [2] returned multiple items or a sequence of strings. You did not specify a predicate / selection criteria so you got an 'array' of strings.

[1] fn:doc("xmldatabasefile.xml")/bookstore/book/title[fn:contains(.,'Learning XML')]
[2] fn:doc("xmldatabasefile.xml")/bookstore/book/title/text()
[3] for $book-title in doc('xmldatabasefile.xml')/bookstore/book/title
Where contains($book-title/text(), 'Learning XML')
Return $book-title/text()


-----Original Message-----
From: talk-***@x-query.com [mailto:talk-***@x-query.com] On Behalf Of e-letter
Sent: Friday, December 27, 2013 6:04 AM
To: ***@w3.org
Cc: ***@x-query.com
Subject: Re: [xquery-talk] xpath1 text node contains attribute, equivalent in xpath2
Post by Liam R E Quin
Post by e-letter
Xpath1 specification § 4.2 string functions
(http://www.w3.org/TR/xpath/#section-String-Functions) describes a
"contains" function, but this was not found in xpath2;
Better to use the XPath 2 Functions and Operators spec, which does
indeed list fn:contains().
{
let $x := fn:doc("xmldatabasefile.xml")/bookstore/book/title[fn:contains(.,'Learning
XML')]/parent::*
return $x
}

returns:

...<p>
<book category="WEB">

<title lang="en">
Learning XML

</title>

<author>Erik T. Ray</author>

<year>2003</year>

<price>39.95</price>

</book>
</p>...

Why is the full stop applied before the comma, because this is not specified as an option in the specification about 'fn:contains'?
Post by Liam R E Quin
Post by e-letter
Is it possible to remove the xml elements from the output file?
Change return $x to return $x/text() maybe
Not quite, returns:

...<p>





</p>...


if 'return' is changed to 'return $x/element()', the result is as 'return $x', but interestingly a removal of new line white space.

_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk

________________________________

The contents of this message may be privileged and confidential. Therefore, if this message has been received in error, please delete it without reading it. Your receipt of this message is not intended to waive any applicable privilege. Please do not disseminate this message without the permission of the author.

Please consider the environment before printing this e-mail
e-letter
2013-12-27 18:07:30 UTC
Permalink
Post by Misztur, Chris
Imagine that query [1] is actually doing a for-each loop on each <title/>
and the predicate in square brackets is applying a 'where' statement on each
iteration. You can also rewrite query [1] as query [3].
The 'let' clause was chosen because it was not considered necessary to
perform any multiple iterations, just a single search for the target.
Is this an incorrect thought-process?
Post by Misztur, Chris
[3] for $book-title in doc('xmldatabasefile.xml')/bookstore/book/title
Where contains($book-title/text(), 'Learning XML')
Return $book-title/text()
This is understood, but the request was also to retrieve the text
nodes of the parent (and parent siblings - uncles/aunts? or maybe
referred to as sibling text nodes? ;) ) elements, i.e.:

Learning XML
Erik T. Ray
2003
39.95

I am unable to append sucessfully '/parent::*' to the 'for' statement above.
Misztur, Chris
2013-12-27 19:05:44 UTC
Permalink
Oh I see what you're trying to do...


xquery version "3.0";

let $bookstore :=
<bookstore>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="XML">
<title>Best XML book</title>
<author>you</author>
<year>2014</year>
<price>1.00</price>
</book>
</bookstore>

let $my-book := $bookstore/book[contains(./title/text(), "Learning")]

(: this works too :)
(: let $my-book := $bookstore/book/title[contains(./text(), "Learning")]/.. :)
(: let $my-book := $bookstore/book/title[contains(./text(), "Learning")]/parent::* :)

(: return <p>{string-join($my-book/string(), codepoints-to-string(10))}</p> :)

return
element table
{
for $element in $my-book/child::*
return
element tr
{
element td { local-name($element)||':' },
element td { $element/text() }
}
}

-----Original Message-----
From: talk-***@x-query.com [mailto:talk-***@x-query.com] On Behalf Of e-letter
Sent: Friday, December 27, 2013 3:20 AM
To: ***@x-query.com
Subject: [xquery-talk] xpath1 text node contains attribute, equivalent in xpath2

Readers,

For an xml file:

...
<book
category="WEB"
<title
lang="en"
Learning XML
</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
...

An xquery file was created and processed using jedit xml plugins:

<html>
<body>
<p>
{
let $x := fn:doc("xmldatabasefile.xml")/bookstore/book/title[contains(text(),'XML')]/parent::*
return $x
}
</p>
</body>
</html>

Xpath1 specification § 4.2 string functions
(http://www.w3.org/TR/xpath/#section-String-Functions) describes a "contains" function, but this was not found in xpath2; what is the equivalent function in xpath2 please?

The resultant output:

<html>
<body>
<p>
<book category="WEB">

<title lang="en">
Learning XML

</title>

<author>Erik T. Ray</author>

<year>2003</year>

<price>39.95</price>

</book>
</p>
</body>
</html>

Is it possible to remove the xml elements from the output file?

An alternative xquery was attempted:

...<p>
{
let $x := fn:doc("xmldatabasefile.xml")/bookstore/book/title/text()
return $x
}
</p>...

Resultant output:

...<p>
Everyday Italian

Harry Potter

XQuery Kick Start

Learning XML

</p>...


Is it possible to select a specific title text with this xquery syntax?

_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk

________________________________

The contents of this message may be privileged and confidential. Therefore, if this message has been received in error, please delete it without reading it. Your receipt of this message is not intended to waive any applicable privilege. Please do not disseminate this message without the permission of the author.

Please consider the environment before printing this e-mail

Loading...