[英]How to extract element value from an xml containing namespaces with xPath in Java?
Environment: Windows 10, Eclipse, Java 1.5 环境: Windows 10,Eclipse,Java 1.5
Objective: I'm trying to obtain the element text value of an xml using xPath. 目标:我正在尝试使用xPath获取xml的元素文本值。 The xml contains various namespaces.
xml包含各种名称空间。
Problem: I always get an empty value. 问题:我总是得到一个空值。
I checked out a few threads on SO but nothing worked. 我在SO上检查了一些线程,但是没有任何效果。 The xml absolute path opens fine on the browser.
xml绝对路径在浏览器上可以正常打开。
This is what I have: 这就是我所拥有的:
//Initialize objects
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
builderFactory.setNamespaceAware(true);
builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(xmlFINAL);//File with absolute path
XPath xPath = (XPath) XPathFactory.newInstance().newXPath();
//NamespaceContext used for xPath
NamespaceContext nsContext = new NamespaceContext (){
public String getNamespaceURI(String prefix) {
if (prefix == null) {
throw new NullPointerException("Null prefix");
} else if ("ns2".equals(prefix)) {
return "http://ns2";
}else{
return "http://ns1";
}
}
public String getPrefix(String namespaceURI) {
return null;
}
public Iterator getPrefixes(String namespaceURI) {
return null;
}
};
xPath.setNamespaceContext(nsContext);
This is a part of the Document content 这是文档内容的一部分
Test xml (mine is too big): 测试xml(我的太大):
<root_element xmlns="http://ns1" xmlns:ns2="http://ns2">
<element1>
...
<ns2:element2>
<ns2:element3>I want this text</element3>
</element2>
...
</element1>
</root_element >
Getting element value (which returns always ""
): 获取元素值(始终返回
""
):
String expression = "/root_element/element1/ns2:element2/ns2:element3/text()";
String valor = (String) xPath.compile(expression).evaluate(xmlDocument,XPathConstants.STRING);
//or
String valor = xPath.evaluate(expression, xmlDocument);
Working fine like that : 这样工作正常:
public static void main(String[] args) throws Exception {
XPathFactory xpf = XPathFactory.newInstance();
XPath path = xpf.newXPath();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
File fileXML = new File("test.xml");
Document xml = builder.parse(fileXML);
Element dataset = xml.getDocumentElement();
NamespaceContext ns = new NamespaceContext() {
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return namespaceURI.equalsIgnoreCase("http://ns1") ? "ns1" : namespaceURI.equalsIgnoreCase("http://ns2") ? "ns2" : "";
}
@Override
public String getNamespaceURI(String prefix) {
return prefix.equalsIgnoreCase("ns1") ? "http://ns1" : prefix.equalsIgnoreCase("ns2") ? "http://ns2" : "";
}
};
path.setNamespaceContext(ns);
String exp1 = "/root_element";
Node root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
exp1 = "/root_element/element1";
root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
exp1 = "/root_element/element1/ns2:element2";
root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
exp1 = "/root_element//ns2:element3";
root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
exp1 = "/root_element//ns2:element3/text()";
String text = (String) path.evaluate(exp1, dataset, XPathConstants.STRING);
System.out.println("Text = " + text);
}
The XML I used : 我使用的XML:
<root_element xmlns="" xmlns:ns1="http://ns1" xmlns:ns2="http://ns2">
<element1>
<ns2:element2>
<ns2:element3>I want this text</ns2:element3>
</ns2:element2>
</element1>
</root_element >
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.