[英]Get XPath of XML Tag
如果我有一個如下的XML文檔:
<foo>
<foo1>Foo Test 1</foo1>
<foo2>
<another1>
<test10>This is a duplicate</test10>
</another1>
</foo2>
<foo2>
<another1>
<test1>Foo Test 2</test1>
</another1>
</foo2>
<foo3>Foo Test 3</foo3>
<foo4>Foo Test 4</foo4>
</foo>
例如,如何獲取<test1>
的XPath? 因此輸出應類似於: foo/foo2[2]/another1/test1
我猜代碼看起來像這樣:
public String getXPath(Document document, String xmlTag) {
String xpath = "";
...
//Get the node from xmlTag
//Get the xpath using the node
return xpath;
}
假設String XPathVar = getXPath(document, "<test1>");
。 我需要找回將在以下代碼中工作的絕對xpath:
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression xpr = xpath.compile(XPathVar);
xpr.evaluate(Document, XPathConstants.STRING);
但這不能像//test1
這樣的快捷方式,因為它也將用於元數據。
通過以下方式打印結果時:
System.out.println(xpr.evaluate(Document, XPathConstants.STRING));
我應該獲取節點的值。 因此,如果XPathVar = foo/foo2[2]/another1/test1
那么我應該回來:
Foo Test 2
,不是This is a duplicate
您不會像沒有“獲取” sql的方式那樣“獲取” xpath。
xpath是基於對xml文檔或架構的理解而編寫的查詢,就像sql是基於對數據庫架構的理解而編寫的查詢一樣-您不會“獲取”它們中的任何一個。
我可以簡單地通過從給定節點上回退節點來從DOM生成xpath語句,盡管這樣做足夠通用,考慮到每個節點上的屬性值,會使生成的代碼幾乎無用。 例如(帶有警告,它將找到具有給定名稱的第一個節點,xpath遠不止於此,您也可以只使用xpath //foo2
):
import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class XPathExample
{
private static String getXPath(Node root, String elementName)
{
for (int i = 0; i < root.getChildNodes().getLength(); i++)
{
Node node = root.getChildNodes().item(i);
if (node instanceof Element)
{
if (node.getNodeName().equals(elementName))
{
return "/" + node.getNodeName();
}
else if (node.getChildNodes().getLength() > 0)
{
String xpath = getXPath(node, elementName);
if (xpath != null)
{
return "/" + node.getNodeName() + xpath;
}
}
}
}
return null;
}
private static String getXPath(Document document, String elementName)
{
return document.getDocumentElement().getNodeName() + getXPath(document.getDocumentElement(), elementName);
}
public static void main(String[] args)
{
try
{
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new ByteArrayInputStream(
("<foo><foo1>Foo Test 1</foo1><foo2><another1><test1>Foo Test 2</test1></another1></foo2><foo3>Foo Test 3</foo3><foo4>Foo Test 4</foo4></foo>").getBytes()
)
);
String xpath = "/" + getXPath(document, "test1");
System.out.println(xpath);
Node node1 = (Node)XPathFactory.newInstance().newXPath().compile(xpath).evaluate(document, XPathConstants.NODE);
Node node2 = (Node)XPathFactory.newInstance().newXPath().compile("//test1").evaluate(document, XPathConstants.NODE);
//This evaluates to true, hence you may as well just use the xpath //test1.
System.out.println(node1.equals(node2));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
同樣,您可以編寫XML轉換,將xml文檔轉換為一系列xpath語句,但是這種轉換將比首先編寫xpath更為復雜,而且毫無意義。
這個怎么樣:
private static String getXPath(Document root, String elementName)
{
try{
XPathExpression expr = XPathFactory.newInstance().newXPath().compile("//" + elementName);
Node node = (Node)expr.evaluate(root, XPathConstants.NODE);
if(node != null) {
return getXPath(node);
}
}
catch(XPathExpressionException e) { }
return null;
}
private static String getXPath(Node node) {
if(node == null || node.getNodeType() != Node.ELEMENT_NODE) {
return "";
}
return getXPath(node.getParentNode()) + "/" + node.getNodeName();
}
請注意,這首先是定位節點(使用XPath),然后使用所定位的節點獲取其XPath。 相當the回的方法來獲取您已經擁有的價值。
可用的ideone示例: http ://ideone.com/EL4783
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.