【问题标题】:How to get the full path of a node in XML file in java?如何在java中获取XML文件中节点的完整路径?
【发布时间】:2013-05-19 11:38:38
【问题描述】:

我有 XPath 解析的 XML 文件以获取其中的所有参数,然后我想获取每个参数的完整路径,但我的代码由于某种原因无法正常工作。 守则:

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

【问题讨论】:

  • 如果您对 XPath 2.0 没问题,我建议在另一个问题的答案中构建这些路径的表达式:stackoverflow.com/a/16491186/695343 - 它也适用于所有属性;返回带有每个属性路径的 XPath 表达式列表。

标签: java xml xpath nodelist xmlnodelist


【解决方案1】:

表达式//*/@* 返回一个空的NodeSet。

下面的代码检索你需要的路径:

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

【讨论】:

  • 哦,对不起,我已经做到了,但是 j
  • 正确的 XPath 表达式是 //@*,注意对 Attr 的强制转换以及使用 getOwnerElement() 代替 getParent()
  • XPath 表达式很好,但对于命名空间 (xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"),他要么必须使用查询 all 命名空间的 //*:*/@*,要么以其他方式处理它们。
  • 好吧,谢谢,我得到了路径,但格式不正确,因为当我尝试查询它时有很多异常,我只想再次使用路径,生成的路径如(#document/rss/channel/item/yweather:forecast/.code) 无法使用。
  • 你错过了节点和属性之间的/,我添加了它。但最后两个查询是相等的,而你的可能是更优雅的一个。我只是想指出命名空间问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多