0

我有一个包含一个 XML 字符串字段的对象列表。我必须对该字段执行类似 SQL 的查询,并获得一个满足这些值的子列表。我正在尝试使用 XPath。

首先,我想不出 XPath 字符串来实现这一点。其次,可能有更好的方法来做到这一点。我尝试通过 SO 进行搜索,但答案并没有真正解决这个问题

细节

我有一个书单:

List <Books> allBooks;

Book 类可以有一个 id 和 details 字段。详细信息是 XML。

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

这是详细信息 xml 字符串的示例:

<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>

所以,直到这里,一切都一成不变。它是现有代码的一部分,我无法更改该设计。

我的工作是获取列表 allBooks 并通过它运行查询,其逻辑是:

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

我考虑将这些数据放入数据库中以运行实际查询,但由于该列表将仅包含几百条记录,因此连接、加载数据等的开销是不值得的。

任何人都知道如何通过 XPath 做到这一点?有更好的方法吗?

4

3 回答 3

1

我们需要账簿记录

//book

与作者“JK罗琳”

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

和流派是“幻想”

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

关键字是“wizard”或“hogwarts”

//book[author = "J K Rowling" and genre = "fantasy" and (keyword = "wizard" or keyword = "hogwarts")]
于 2012-12-05T16:03:54.210 回答
1

您需要首先构建 XPath 查询。我建议您参考之前的答案(hoaz 在这里有一个很好的列表)。然后,您需要编写代码来编译查询并对其进行评估。例子:

  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;
  }

您可以扩展这样的方法以获取查询参数以动态构建 XPath 查询,但这应该会给您基本的想法。

于 2012-12-05T16:31:00.780 回答
0

假设Books是根

/Books/Book[(author = "J K Rowling") and (genre = "fantasy") and (keyword = "wizard" or keyword = "hogwarts")]
于 2012-12-05T16:05:28.447 回答