这个Java XML-Parsing代码有什么问题?

时间:2012-01-04 14:34:33

标签: java xml parsing

我正在尝试解析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而不是文本。

这是一个错误还是我做错了?为什么? :(

非常感谢您的帮助!

问候,Flo

4 个答案:

答案 0 :(得分:4)

你正在调用Node.getNodeValue() - 当你在一个元素上调用它时,它被记录为返回null。您应该拨打getTextContent() - 或者使用更高级别的API。

答案 1 :(得分:3)

正如其他人在我之前提到的,你似乎正在重塑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界面已记录hereaforementioned article中还有一些示例。

此外,还有用于XML操作的第三方库,您可能会发现这些库更方便,例如dom4j(由duffymo建议)或JDOM。无论您使用哪个库,都可以使用功能强大的XPath语言。

答案 2 :(得分:2)

因为您使用的是getNodeValue()而不是getTextContent()

手工做这件事是等待发生的事故;要么使用内置的XPath解决方案,要么使用@duffymo建议的第三方库。这不是重新发明增加价值的情况,IMO。

答案 3 :(得分:1)

我想知道你为什么不使用像dom4j这样的库和内置的XPath。您正在使用非常低级的API(WC3 DOM)进行大量工作。

逐步使用调试器,查看<spam>节点具有的子节点。你应该快速弄清楚它为什么是空的。它会比在这里要求更快。