2013-05-19 3 views
3

J'ai fichier XML analysé par XPath pour obtenir tous les paramètres, puis je veux obtenir le chemin complet à chaque paramètre, mais mon code ne fonctionne pas pour une raison quelconque. Le code:Comment obtenir le chemin complet d'un noeud dans un fichier XML dans 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

Si vous êtes bien avec XPath 2.0, je propose une expression dans la construction de ces pathes une réponse à une autre question: http://stackoverflow.com/ a/16491186/695343 - cela fonctionnera bien pour tous les attributs, aussi; retourne une liste d'expressions XPath avec un chemin pour chaque attribut. –

Répondre

2

L'expression //*/@* retourne un NodeSet vide.

Le code ci-dessous récupérer les chemins dont vous avez besoin:

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

oh, désolé, je l'ai déjà fait comme ça mais le j <2 était une chose de test, j'ai édité le code dans ma question. –

+0

L'expression XPath droit est // @ *, notez la distribution à Attr et l'utilisation de getOwnerElement() à la place de getParent() – Aubin

+0

L'expression XPath était bien, mais pour les espaces de noms ('xmlns: yweather =" http: // xml .weather.yahoo.com/ns/rss/1.0 "xmlns: geo =" http://www.w3.org/2003/01/geo/wgs84_pos# "), soit il devrait utiliser' // * : */@ * 'qui interroge tous les espaces de noms ou les traite d'une autre manière. –

Questions connexes