Получение значения атрибута в Java из XML с использованием XPath

1

В настоящее время я использую XPath для получения некоторой информации из подкаста с использованием Java и XPath. Я пытаюсь прочитать атрибут узла:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:atom="http://www.w3.org/2005/Atom/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
  <channel>
    [....]
    <itunes:image href="http://icebox.5by5.tv/images/broadcasts/14/cover.jpg" />
[...]

Я хочу получить значение атрибута href в <itunes: image>. В настоящее время я использую следующий код:

private static String IMAGE_XPATH = "//channel/itunes:image/@href";
String imageUrl = xpath.compile(IMAGE_XPATH).evaluate(doc, XPathConstants.STRING).toString();

Результат imageUrl равен null. Что происходит в коде? У меня есть ошибка в коде XPath или в коде Java?

Благодарю! :)

Теги:
xpath

2 ответа

4
Лучший ответ

Отключить awespace пространства имен:

DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
xmlFact.setNamespaceAware(false);

Ваше выражение xpath должно выглядеть следующим образом:

"//channel/image/@href"

Если вам нужно использовать его в качестве пространства имен, просто выполните свой собственный NameSpaceContext, он должен выглядеть так:

NamespaceContext ctx = new ItunesNamespaceContext();

XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath();
xpath.setNamespaceContext(ctx);
String IMAGE_XPATH = "//channel/itunes:image/@href";
String imageUrl = path.compile(IMAGE_XPATH).evaluate(doc,XPathConstants.STRING).toString();

EDIT: Вот тестовый код, который доказывает мою мысль:

String a ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><rss xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:sy=\"http://purl.org/rss/1.0/modules/syndication/\" xmlns:admin=\"http://webns.net/mvcb/\" xmlns:atom=\"http://www.w3.org/2005/Atom/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\" xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\" version=\"2.0\"><channel><itunes:image href=\"http://icebox.5by5.tv/images/broadcasts/14/cover.jpg\" /></channel></rss>";
DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
xmlFact.setNamespaceAware(false);
DocumentBuilder builder = xmlFact.newDocumentBuilder();
XPathFactory xpathFactory = XPathFactory.newInstance();
String expr = "//channel/image/@href";
XPath xpath = xpathFactory.newXPath();
Document doc = builder.parse(new InputSource(new StringReader(a)));
String imageUrl = (String) xpath.compile(expr).evaluate(doc ,XPathConstants.STRING);
System.out.println(imageUrl);

Выход:

http://icebox.5by5.tv/images/broadcasts/14/cover.jpg
  • 0
    Здравствуй. Я не думаю, что пространства имен являются проблемой, потому что я уже использую другие выражения XPath для получения тегов itunes:.
  • 1
    Я только что добавил фрагмент кода, доказывающий, что этот ответ правильный, <itunes: не определяет тег, но тип, к которому относится тег, прочитайте это руководство, если вы не понимаете, что такое пространства имен: w3schools.com /xml/xml_namespaces.asp
0

XPath должен включать корневой элемент, поэтому rss/channel/itunes: image/@href.

Кроме того, вы можете запустить xpath с помощью //, чтобы все уровни искали xpath (//channel/itunes: image/@href), но если корневой каталог всегда будет одинаковым, более эффективно использовать первый вариант,

  • 0
    Здравствуй. Я попытался изменить XPath, чтобы использовать ваш код, но он по-прежнему возвращает ноль
  • 0
    Может ли быть так, что XPath возвращает весь атрибут, я имею в виду, не только его значение, но и как объект, который содержит эту часть DOM?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню