2009-02-12 7 views
13

Tôi muốn sử dụng JDOM để đọc trong một tệp XML, sau đó sử dụng XPath để trích xuất dữ liệu từ Tài liệu JDOM. Nó tạo ra đối tượng Document tốt, nhưng khi tôi sử dụng XPath để truy vấn Document cho một List of elements, tôi không nhận được gì cả.Vùng tên XML mặc định, JDOM và XPath

Tài liệu XML của tôi có một không gian tên mặc định được xác định trong phần tử gốc. Điều thú vị là, khi tôi loại bỏ không gian tên mặc định, nó chạy thành công truy vấn XPath và trả về các phần tử mà tôi muốn. Tôi phải làm gì khác để nhận được truy vấn XPath của mình để trả lại kết quả?

XML:

<?xml version="1.0" encoding="UTF-8"?> 
<collection xmlns="http://www.foo.com"> 
<dvd id="A"> 
    <title>Lord of the Rings: The Fellowship of the Ring</title> 
    <length>178</length> 
    <actor>Ian Holm</actor> 
    <actor>Elijah Wood</actor> 
    <actor>Ian McKellen</actor> 
</dvd> 
<dvd id="B"> 
    <title>The Matrix</title> 
    <length>136</length> 
    <actor>Keanu Reeves</actor> 
    <actor>Laurence Fishburne</actor> 
</dvd> 
</collection> 

Java:

public static void main(String args[]) throws Exception { 
    SAXBuilder builder = new SAXBuilder(); 
    Document d = builder.build("xpath.xml"); 
    XPath xpath = XPath.newInstance("collection/dvd"); 
    xpath.addNamespace(d.getRootElement().getNamespace()); 
    System.out.println(xpath.selectNodes(d)); 
} 

Trả lời

26

XPath 1.0 không hỗ trợ các khái niệm về một không gian tên mặc định (XPath 2.0 không). Bất kỳ thẻ không cố định nào luôn được giả định là một phần của không gian tên không có tên.

Khi sử dụng XPath 1.0 bạn cần một cái gì đó như thế này:

public static void main(String args[]) throws Exception { 
    SAXBuilder builder = new SAXBuilder(); 
    Document d = builder.build("xpath.xml"); 
    XPath xpath = XPath.newInstance("x:collection/x:dvd"); 
    xpath.addNamespace("x", d.getRootElement().getNamespaceURI()); 
    System.out.println(xpath.selectNodes(d)); 
} 
+0

Bí quyết, cảm ơn! – Michael

+0

Điều này thật tuyệt vời, tôi đã dành 3 giờ đồng hồ để tự hỏi tại sao XPath của tôi đột nhiên không hoạt động và đó là điều này. Pffh! :) – Esko

+0

x là gì? – Meinkraft

6

Tôi đã có một vấn đề tương tự, nhưng tôi là tôi đã có một hỗn hợp của nguyên liệu đầu vào XML, một số trong đó đã có một không gian tên được xác định và những người khác điều đó không có. Để đơn giản hóa vấn đề của tôi, tôi chạy đoạn mã JDOM sau đây sau khi tải tài liệu.

for (Element el : doc.getRootElement().getDescendants(new ElementFilter())) { 
    if (el.getNamespace() != null) el.setNamespace(null); 
} 

Sau khi loại bỏ tất cả các không gian tên tôi đã có thể sử dụng đơn giản getChild ("elname") chuyển hướng phong cách hoặc truy vấn XPath đơn giản.

Tôi sẽ không đề xuất kỹ thuật này như một giải pháp chung, nhưng trong trường hợp của tôi, nó chắc chắn hữu ích.

+0

Cảm ơn bạn đã đề xuất. Tôi đã nghĩ đến việc làm một cái gì đó như thế này, nhưng giống như bạn đã ám chỉ, loại bỏ các không gian tên có nghĩa là có khả năng bạn sẽ chạy vào các xung đột tên, tùy thuộc vào dữ liệu XML của bạn trông như thế nào. – Michael

1

Bạn cũng có thể làm như sau

/*[local-name() = 'collection']/*[local-name() = 'dvd']/

Here là danh sách các truy vấn xpath hữu ích.