Question: I have a list of objects which contain one XML String field. I have to execute an SQL like query for that field, and get a sub list that satisfies the values. I am trying to use XPath. 

Firstly, I can't figure out the XPath string to achieve this. Secondly, there might be a better way of doing this. I tried searching through SO but the answers don't really address this problem

**Details**
-----------

I have a list of books:

```
List <Books> allBooks;

```

The Book class can have an id and details fields. The details is XML.

```
class Book
{
    String id;
    String details; //XML
}

```

Here is a sample of the details xml String:

```
<book>
   <name>Harry Potter and the sorcerer's stone</name>
   <author>J K Rowling</author>
   <genre>fantasy</genre>
   <keyword>wizard</keyword>
   <keyword>british</keyword>
   <keyword>hogwarts</keyword>
   <price>25</price>
</book>

```

So, uptil here it is all set in stone. It is part of existing code and I cannot change that design.

My work is to take the list allBooks & run a query through it, the logic of which is:

```
   WHERE author = "J K Rowling" AND
     genre = "fantasy" AND
     (keyword = "wizard" OR keyword="hogwarts")

```

I considered throwing this data in a DB to run an actual query, but since the list will only contain a couple of hundred records, the overhead of connection, loading data etc is not worth it.

Anyone know how to do this through XPath? Any better way of doing this?

Answer: 
We need book records

```
//book

```

with author "J K Rowling"

```
//book[author = "J K Rowling"]

```

and genre is "fantasy"

```
//book[author = "J K Rowling" and genre = "fantasy"]

```

and keyword is "wizard" or "hogwarts"

```
//book[author = "J K Rowling" and genre = "fantasy" and (keyword = "wizard" or keyword = "hogwarts")]

```
You need to build the XPath queries first. I recommend referring to a previous answer for those (hoaz has a good listing [here](https://stackoverflow.com/a/13727372/460638)). Then you need to write the code to compile the query and evaluate it. Example:

```
  public List<Book> findBookInformation(List<Books> books)  
      throws ParserConfigurationException, SAXException, 
         IOException, XPathExpressionException {

    List<Book> foundBooks = new ArrayList<Book>(); // books matching criteria

    for (Book book : books) {
      DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
      domFactory.setNamespaceAware(true); // never forget this!
      DocumentBuilder builder = domFactory.newDocumentBuilder();
      Document doc = builder.parse(new InputSource(new StringReader(book.details))); // parse details XML into a Doc object

      XPathFactory factory = XPathFactory.newInstance();
      XPath xpath = factory.newXPath();
      //using one of the query examples
      XPathExpression expr = xpath.compile("/book[author = \"J K Rowling\" and genre = \"fantasy\" and (keyword = \"wizard\" or keyword = \"hogwarts\")]");

      Object result = expr.evaluate(doc, XPathConstants.NODESET); 
      NodeList nodes = (NodeList) result;
      if (null != nodes && nodes.getLength() > 0) {
        foundBooks.add(book); // add to your return list
      }
    }
    return foundBooks;
  }

```

You could extend a method like this to take in your query arguments to dynamically build your XPath query, but this should give you the basic idea.