我正在尝试通过 XPath 从 XML 文件中提取数据
。我的代码在没有命名空间的 XML
上运行,但由于我的代码有命名空间,所以我向 X Path 对象添加了必要的 NamespaceContext
。不幸的是,XPath
没有提供任何数据,因此经过一番摆弄后,我的代码最终保持不变,但这个 jar xmlparserv2.jar
添加到了类路径中。瞧,突然间一切都完美了。
我可以看到该 jar 包含 JDK
(1.7.0_15) 中已有的类,但可能是不同的版本。
所以我的问题是
a) 除了我必须通过无休止的类
进行调试之外,有没有办法找出JDK
中的原始类出了什么问题?
b) 有没有人有替代解决方案的想法/如何更改我的代码,这样我就不必发送额外的“不必要的”jar
?
谢谢 西蒙
这就是有问题的代码:
public class JavaApplication1 {
public static void main(String[] args) throws IOException, SAXException {
Document doc = createDoc("Persons.xml");
parseSFMessage(doc);
}
private static void parseSFMessage(Node node) {
if (node.getNodeName().startsWith("Persons:person") && node.hasChildNodes()) {
print("PLZ: " + getNodeValue(node, "ns1:PLZ"));
}
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node currentNode = nodeList.item(i);
if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
parseSFMessage(currentNode);
}
}
}
private static Document createDoc(String s) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
Document doc = null;
try {
builder = factory.newDocumentBuilder();
doc = builder.parse(new FileInputStream(s));
} catch (SAXException e) {
} catch (IOException e) {
} catch (ParserConfigurationException e) {
}
return doc;
}
private static String getNodeValue(Node dom, String element) {
NamespaceContext ctx = new NamespaceContext() {
public String getNamespaceURI(String prefix) {
String uri;
if (prefix.equals("ns1")) {
uri = "http://someurl.com/schemas/class/Utils";
} else {
uri = null;
}
return uri;
}
public Iterator getPrefixes(String val) {
return null;
}
public String getPrefix(String uri) {
return null;
}
};
String result = null;
XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
xp.setNamespaceContext(ctx);
try {
result = xp.evaluate(element, dom);
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return result;
}
private static void print(Object o) {
if (o != null) {
System.out.println(o.toString());
}
}
}
最佳答案
您需要注意,默认情况下,DocumentBuilderFactory
不识别命名空间。在执行 factory.newDocumentBuilder()
之前,您必须调用 factory.setNamespaceAware(true);
,以便获得能够通过命名空间支持正确解析 XML 的构建器。
至于为什么它与 xmlparserv2
一起使用,我只能推测,也许该特定解析器违反了 JAXP 规范并默认启用 namespace 。
关于Java XPath 仅在添加不必要的 jar 后才起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15042260/