#java #dom #xpath
#java #dom #xpath
Вопрос:
У меня есть xml. Я хочу получить / распечатать Xpath (полный) всех узлов в нем, используя Java. Я пытаюсь использовать анализатор 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());
Я могу заставить свой корневой узел печатать, но не его дочерние элементы.
Комментарии:
1. Я не уверен, почему это было отклонено.
Ответ №1:
Как ни странно, я только что написал метод, который можно было бы использовать для этого. Однако это не полностью учитывает пространство имен, поэтому имейте в виду, что оно также работает только для типов ЭЛЕМЕНТОВ.
Чтобы этот метод работал, вам также необходимо, чтобы ваш документ знал пространство имен. 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 amp;amp; elt.getParentNode().getNodeType() == Element.ELEMENT_NODE)
elt = (Element) elt.getParentNode();
else
elt = null;
} while(elt != null amp;amp; !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()) amp;amp;
(element.getNamespaceURI() == original.getNamespaceURI() || (element.getNamespaceURI() != null amp;amp; element.getNamespaceURI().equals(original.getNamespaceURI())))) {
count ;
}
}
}
return count;
}