Проблема с использованием xpath для чтения тегов xhtml

Я использую xpath для чтения документа xhtml, я хочу прочитать все элементы внутри тега <p> файла xhtml. Для этого я делаю что-то вроде этого.

XPath xpath = XPathFactory.newInstance().newXPath();                
XPathExpression expr = xpath.compile("//p[2]/*");                 
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
    System.out.println("Nodes>>>>>>>>"+nodes.item(i).getNodeValue());
}

Образец XHMTL выглядит так.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head><title>test</title></head>
    <body>
        <p class="default"> <span style="color: #000000; font-size: 12pt; font-family: sans-serif"> Test Doc</span> </p> 
        <p class="default"> <span style="color: #000000; font-size: 12pt; font-family: sans-serif"> Test Doc1</span> </p>
        <p class="default"> <span style="color: #000000; font-size: 12pt; font-family: sans-serif"> Test Doc2</span> </p>
    </body>
</html>

Но я не могу получить узлы внутри тега <p>, не могу войти в цикл for.

Может ли кто-нибудь помочь мне в решении этой проблемы.

заранее спасибо


person user972590    schedule 02.11.2011    source источник
comment
я новичок в этом, вы можете дать подробный ответ   -  person user972590    schedule 02.11.2011
comment
Пожалуйста, добавьте к своему вопросу образец XHTML - полный файл, включая тег html, - который, как вы ожидаете, будет работать, но не работает.   -  person Alohci    schedule 02.11.2011
comment
Если вы используете пространства имен, это может быть причиной того, что вы не можете получить доступ к тегу. Для этого вы можете уточнить выражение xpath, чтобы оно выглядело как .//*[local-name()='p']. Это вернет узлы без учета пространства имен.   -  person Kris    schedule 02.11.2011
comment
@Alohci, я отредактировал свой вопрос, добавив образец файла xhtml, пожалуйста, посмотрите   -  person user972590    schedule 02.11.2011
comment
@Krishnanunni, теперь я могу получить значения узла, используя локальное имя, спасибо за ваше время. Если у меня есть несколько абзацев, и я хочу получить доступ к определенному абзацу на основе, скажем, некоторого идентификатора, как я могу с этим справиться?   -  person user972590    schedule 02.11.2011
comment
Я разместил ответ. Попытайся.   -  person Kris    schedule 02.11.2011


Ответы (3)


       XPathExpression expr = xpath.compile(".//*[local-name()='p'][@id='ur_id']");               

Вы можете это проверить? Я думаю, что это даст вам ваш узел. Будет приятно посетить http://saxon.sourceforge.net/saxon6.5/expressions.html и понимать основы парсинга XPath.

person Kris    schedule 02.11.2011
comment
//XXX[@attrib='abc'] выберет узел с атрибутом attrib='abc' - person Kris; 02.11.2011

Ваш код пытается напечатать nodeValues узлов Element, что вряд ли будет тем, что вам нужно. Я ожидаю, что вам нужны nodeValue текстовых узлов.

Другой проблемой может быть пространство имен. Похоже, что ваш xpath пытается сопоставить элементы p без пространства имен, тогда как, вероятно, он должен пытаться сопоставить элементы p в пространстве имен http://www.w3.org/1999/xhtml.

person Alohci    schedule 02.11.2011

Вы можете использовать XPathAPI (javadoc), чтобы извлечь узлы в виде общего списка Java.

String expr = "//p[2]/*";

Map<String, String> ns = new Map<String, String>;
ns.put("html", "http://www.w3.org/1999/xhtml");

List<String> nodeValues = XPathAPI.html.selectNodeListAsStrings(doc, expr, ns);
for (String nodeValue : nodesValues) {
    System.out.println("Nodes>>>>>>>> " + nodeValue);
}

or

List<String> nodeValues = XPathAPI.html.selectListOfNodes(doc, expr, ns);
for (Node node : nodes) {
    System.out.println("Nodes>>>>>>>> " + node.getTextContent());
}

Отказ от ответственности: я являюсь автором библиотеки XPathAPI.

person gioele    schedule 02.11.2011