这个Java XML解析代码有什么问题?
我试图解析一个XML文件,并能够插入一个路径并获得该字段的值。这个Java XML解析代码有什么问题?
它看起来如下:
import java.io.IOException;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
public class XMLConfigManager {
private Element config = null;
public XMLConfigManager(String file) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
Document domTree;
DocumentBuilder db = dbf.newDocumentBuilder();
domTree = db.parse(file);
config = domTree.getDocumentElement();
}
catch (IllegalArgumentException iae) {
iae.printStackTrace();
}
catch (ParserConfigurationException pce) {
pce.printStackTrace();
}
catch (SAXException se) {
se.printStackTrace();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
public String getStringValue(String path) {
String[] pathArray = path.split("\\|");
Element tempElement = config;
NodeList tempNodeList = null;
for (int i = 0; i < pathArray.length; i++) {
if (i == 0) {
if (tempElement.getNodeName().equals(pathArray[0])) {
System.out.println("First element is correct, do nothing here (just in next step)");
}
else {
return "**This node does not exist**";
}
}
else {
tempNodeList = tempElement.getChildNodes();
tempElement = getChildElement(pathArray[i],tempNodeList);
}
}
return tempElement.getNodeValue();
}
private Element getChildElement(String identifier, NodeList nl) {
String tempNodeName = null;
for (int i = 0; i < nl.getLength(); i++) {
tempNodeName = nl.item(i).getNodeName();
if (tempNodeName.equals(identifier)) {
Element returner = (Element)nl.item(i).getChildNodes();
return returner;
}
}
return null;
}
}
的XML看起来像这样(用于测试目的):
<?xml version="1.0" encoding="UTF-8"?>
<amc>
<controller>
<someOtherTest>bla</someOtherTest>
<general>
<spam>This is test return String</spam>
<interval>1000</interval>
</general>
</controller>
<agent>
<name>test</name>
<ifc>ifcTest</ifc>
</agent>
</amc>
现在我可以调用类这样
XMLConfigManager xmlcm = new XMLConfigManager("myConfig.xml");
System.out.println(xmlcm.getStringValue("amc|controller|general|spam"));
这里,我期待标签spam
的价值,所以这将是“This is test return String
”。但我得到null
。
我试图解决这个问题好几天了,我无法得到它。迭代可以工作,所以它会到达标记spam
,但是,正如我所说的那样,它会返回null
而不是文本。
这是一个错误还是我只是做错了?为什么? :(
非常感谢您的帮助!
问候,弗洛
正如其他人在我之前提到的,您似乎在重塑XPath的概念。你可以用下面的代码替换代码:
javax.xml.xpath.XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
String expression = "/amc/controller/general/spam";
org.xml.sax.InputSource inputSource = new org.xml.sax.InputSource("myConfig.xml");
String result = xpath.evaluate(expression, inputSource);
参见:XML Validation and XPath Evaluation in J2SE 5.0
编辑:
使用XPath提取收集的一个例子:
NodeList result = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
for (int i = 0; i < result.getLength(); i++) {
System.out.println(result.item(i).getTextContent());
}
的javax.xml.xpath.XPath
界面被记录为here,并且还有几个考试在aforementioned article。
此外,还有第三方库用于XML操作,您可能会发现更方便,例如dom4j(由duffymo建议)或JDOM。无论您使用哪个库,都可以使用功能非常强大的XPath语言。
如果零件'
(小例子:) – 2012-01-04 16:34:33
为什么你不使用图书馆像dom4j和内置的XPath我不知道。你做了很多使用非常低级别的API(WC3 DOM)工作
用调试器逐步完成并查看子节点有哪些子节点,你应该快速找出它为什么是空的,它会比在这里询问要快。
你打给我Node.getNodeValue()
- 将其记录为在元素上调用时返回null。您应该拨打getTextContent()
,或者使用更高级别的API,当然。
因为您使用getNodeValue()
而不是getTextContent()
。
用手做这件事是等待发生的事故;可以使用@duffymo建议的内置XPath解决方案或第三方库。这不是重新发明增加价值的情况,IMO。
你可能会更进一步。如果在你的循环中,你会得到那个|中所有元素的子元素分隔列表中,最后返回的值将是“垃圾邮件”的子元素,它不存在。 – Tudor 2012-01-04 14:40:11
自从JavaSE 5以来,Java已经有了一个XPath库。它可以在'javax.xml.xpath'包中找到。 – Dev 2012-01-04 14:42:42