2013-05-19 4 views
3

У меня есть XML-файл, обработанный XPath, чтобы получить все параметры в нем, а затем я хочу получить полный путь к каждому параметру, но по какой-то причине мой код не работал. Кодекс:Как получить полный путь узла в файле XML в java?

ArrayList<String> names = new ArrayList<String>(); 
ArrayList<String> paths = new ArrayList<String>(); 
URL oracle = new URL("http://weather.yahooapis.com/forecastrss?w=2502265"); 
InputStream is = oracle.openStream(); 
org.w3c.dom.Document doc = null; 
DocumentBuilderFactory domFactory; 
DocumentBuilder builder; 
try { 
    domFactory = DocumentBuilderFactory.newInstance(); 
    domFactory.setNamespaceAware(true); 
    builder = domFactory.newDocumentBuilder(); 
    doc = builder.parse(is); 
} catch (Exception ex) { 
    System.err.println("unable to load XML: " + ex); 
} 

XPathFactory factory = XPathFactory.newInstance(); 
XPath xpath = factory.newXPath(); 
XPathExpression expr = xpath.compile("//*/@*"); 
Object result = expr.evaluate(doc, XPathConstants.NODESET); 
NodeList nl = (NodeList) result; 
for(int j=0 ; j < nl.getLength() ; j++){ 
    names.add(nl.item(j).getNodeName()); 
    Node node = nl.item(j); 
    ArrayList<String> parents = new ArrayList<String>(); 
    while(node.getParentNode() != null){ // it didn't even gone through this loop 
     parents.add(node.getNodeName()); 
     node = node.getParentNode(); 
    } 
    System.out.println(parents); 
}  
+0

Если вы хорошо с XPath 2.0, я предложил выражение строит эти тракты в ответ на другой вопрос: http://stackoverflow.com/ a/16491186/695343 - он будет отлично работать и для всех атрибутов; возвращая список выражений XPath с указанием пути для каждого атрибута. –

ответ

2

Выражение //*/@* возвращает пустой набор узлов.

ниже код извлечения пути вам нужно:

import org.w3c.dom.Attr; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

public class SO { 

    @SuppressWarnings("nls") 
    public static void main(String[] args) throws Exception { 
     List<String> names = new ArrayList<>(); 
     URL oracle = 
     new URL("http://weather.yahooapis.com/forecastrss?w=2502265"); 
     InputStream is = oracle.openStream(); 
     org.w3c.dom.Document doc = null; 
     DocumentBuilderFactory domFactory; 
     DocumentBuilder builder; 
     try { 
     domFactory = DocumentBuilderFactory.newInstance(); 
     domFactory.setNamespaceAware(true); 
     builder = domFactory.newDocumentBuilder(); 
     doc = builder.parse(is); 
     } catch (Exception ex) { 
     System.err.println("unable to load XML: " + ex); 
     } 
     XPathFactory factory = XPathFactory.newInstance(); 
     XPath xpath = factory.newXPath(); 
     XPathExpression expr = xpath.compile("//*:*/@*"); 
     Object result = expr.evaluate(doc, XPathConstants.NODESET); 
     NodeList nl = (NodeList) result; 
     for(int j=0 ; j < nl.getLength() ; j++){ 
     names.add(nl.item(j).getNodeName()); 
     Node node = nl.item(j); 
     String path = "." + node.getNodeName() + " = " + node.getNodeValue(); 
     node = ((Attr)node).getOwnerElement(); 
     while(node != null) { 
      path = node.getNodeName() + '/' + path; 
      node = node.getParentNode(); 
     } 
     System.out.println(path); 
     } 
    } 
} 
+0

ой, извините, я уже сделал это так, но j <2 был испытанием, я редактировал код в своем вопросе. –

+0

Правильное выражение XPath // @ *, обратите внимание на приведение в Attr и использование getOwnerElement() вместо getParent() – Aubin

+0

Выражение XPath было прекрасным, но для пространств имен ('xmlns: yweather =" http: // xml .weather.yahoo.com/ns/rss/1.0 "xmlns: geo =" http://www.w3.org/2003/01/geo/wgs84_pos# "'), либо он должен будет использовать '// * : */@ * ', который запрашивает _all_ пространства имен или обрабатывает их по-другому. –