【问题标题】:Obtaining Xpath of all nodes in an xml获取xml中所有节点的Xpath
【发布时间】:2014-08-17 16:53:08
【问题描述】:

我有一个 xml。我想使用 Java 获取/打印其中所有节点的 Xpath(complete)。我正在尝试使用 DOM 解析器。

File stocks = new File("File Name");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
Document doc = dBuilder.parse(stocks); 
System.out.println("Parsed successfully"); 
doc.getDocumentElement();        
System.out.println("root of xml file : " + doc.getDocumentElement().getNodeName());

我可以打印我的根节点,但不能打印它的子节点。

【问题讨论】:

  • 我不知道为什么这被否决了。

标签: java dom xpath


【解决方案1】:

奇怪的是,我刚刚编写了一个可以用于此的方法。然而,这并不完全支持命名空间,因此请注意,它也仅适用于 ELEMENT 类型。


要使此方法起作用,您还需要您的文档能够识别名称空间。 dbFactory.setNamespaceAware(true);。如果你不能让它知道命名空间,那么将你看到的任何地方都替换为getLocalName() 到getTagName()。


try {
    XPath xpath = XPathFactory.newInstance().newXPath();
    // get all nodes in the document
    NodeList nList = (NodeList) xpath.evaluate("//*", doc.getDocumentElement() ,XPathConstants.NODESET);

    for(int i=0;i<nList.getLength();i++) {
        if(nList.item(i).getNodeType() == Node.ELEMENT_NODE)
            System.out.println(getElementXPath((Element)nList.item(i), doc.getDocumentElement()));
    }
} catch (XPathExpressionException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}


 /**
 * Finds the xPath relative to the given node, the relativeTo should always be a parent of elt
 * @param elt 
 * @param relativeTo should be a parent of elt, if it isnt the path from the document root will be returned
 * @return
 */
public static String getElementXPath(Element elt, Element relativeTo) {
    String path = ""; 

    do {
        String xname = elt.getLocalName() + "[" + getElementIndex(elt) + "]";
        path = "/" + xname + path;

        if(elt.getParentNode() != null && elt.getParentNode().getNodeType() == Element.ELEMENT_NODE)
            elt = (Element) elt.getParentNode();
        else
            elt = null;
    } while(elt != null && !elt.equals(relativeTo));

    return path;                            
}

/**
 * @param original
 * @return the index this element is among its siblings, only accounts for siblings with the same tag name as itself. Used for xpath indexing
 */
private static int getElementIndex(Element original) {
    int count = 1;

    for (Node node = original.getPreviousSibling(); node != null; node = node.getPreviousSibling()) {
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            if (element.getLocalName().equals(original.getLocalName()) && 
                    (element.getNamespaceURI() == original.getNamespaceURI() || (element.getNamespaceURI() != null && element.getNamespaceURI().equals(original.getNamespaceURI())))) {
                count++;
            }
        }
    }

    return count;
}

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2023-03-27
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多