2009-02-12 2 views
13

Я хочу использовать JDOM для чтения в XML-файле, а затем использовать XPath для извлечения данных из документа JDOM. Он создает объект Document fine, но когда я использую XPath для запроса документа для списка элементов, я ничего не получаю.По умолчанию пространство имен XML, JDOM и XPath

В моем XML-документе есть пространство имен по умолчанию, определенное в корневом элементе. Самое смешное, когда я удаляю пространство имен по умолчанию, он успешно запускает запрос XPath и возвращает те элементы, которые я хочу. Что еще я должен сделать, чтобы получить запрос XPath для получения результатов?

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

ответ

26

XPath 1,0 не поддерживает концепцию пространства имен по умолчанию (XPath 2.0 делает). Любой немаркированный тег всегда считается частью пространства имен без имени.

При использовании XPath 1.0 вам нужно что-то вроде этого:

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

Сделал трюк, спасибо! – Michael

+0

Это отлично, я провел последние 3 часа, задаваясь вопросом, почему мой XPath внезапно не работает, и это было так. Pffh! :) – Esko

+0

что такое x для? – Meinkraft

6

Я имел похожую проблему, но мое было то, что у меня была смесь входов XML, некоторые из которых имели пространство имен определены и другие это не так. Чтобы упростить мою проблему, я загрузил следующий фрагмент JDOM после загрузки документа.

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

После удаления всех пространств имен я был в состоянии использовать простой GetChild («elname») стиля навигацию или простые запросы XPath.

Я бы не рекомендовал эту технику в качестве общего решения, но в моем случае это было определенно полезно.

+0

Спасибо за предложение. Я подумал о том, чтобы сделать что-то подобное, но, как и вы, вы упомянули об этом, удаление пространств имен означает, что есть вероятность, что вы столкнетесь с конфликтами имен, в зависимости от того, как выглядят ваши XML-данные. – Michael

1

Вы также можете сделать следующее

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

Here является список полезных запросов XPath.

Смежные вопросы