satish
satish

Reputation: 297

XML child elements are not being selected by XPath with local-name() function

I was looking at an example in W3 school website and they were able to display title element value by imposing condition on price element.

Working XPATH expression without namespaces.

/bookstore/book[price>35]/title

However when I changed the same xml to have name spaces and displaying price element value by imposing condition on author element, I am seeing exception. Below is the XPATH expression with namespaces.

/*[local-name()='bookstore']/*[local-name()='book'[local-name()='author' and text()='Giada De Laurentiis']]/*[local-name()='price']

It is failing with exception

Exception in thread "main" javax.xml.transform.TransformerException: ERROR! Unknown op code: 21
    at com.sun.org.apache.xpath.internal.compiler.Compiler.error(Unknown Source)
    at com.sun.org.apache.xpath.internal.compiler.OpMap.getFirstPredicateOpPos(Unknown Source)
    at com.sun.org.apache.xpath.internal.axes.WalkerFactory.analyzePredicate(Unknown Source)

Could you please let me know what is wrong with XPATH expression having namespaces?

XML with name spaces

<?xml version="1.0" encoding="UTF-8"?>
<bk:bookstore xmlns:bk = "http://www.example.com/" xmlns:typ = "http://www.example.com/types">
<bk:book category = "COOKING">
    <typ:title lang = "en">Everyday Italian</typ:title>
    <typ:author>Giada De Laurentiis</typ:author>
    <typ:year>2005</typ:year>
    <typ:price>30.00</typ:price>
</bk:book>
<bk:book category = "CHILDREN">
    <typ:title lang = "en">Harry Potter</typ:title>
    <typ:author>J K. Rowling</typ:author>
    <typ:year>2005</typ:year>
    <typ:price>29.99</typ:price>
</bk:book>
<bk:book category = "WEB">
    <typ:title lang = "en">XQuery Kick Start</typ:title>
    <typ:author>James McGovern</typ:author>
    <typ:year>2003</typ:year>
    <typ:price>49.99</typ:price>
</bk:book>

Upvotes: 3

Views: 1273

Answers (1)

kjhughes
kjhughes

Reputation: 111591

You really shouldn't skirt namespaces in this manner, but if you insist, here is a local-name() based XPath, line-broken for readability, to select the price element for the book whose author is "Giada De Laurentiis" within the bookstore element:

/*[local-name()='bookstore']
/*[local-name()='book' and *[local-name()='author' and .='Giada De Laurentiis']]
/*[local-name()='price']

Upvotes: 3

Related Questions