0

我有以下内容:

public static void main(String args[]) {

     // upload config' data for program - param' are path and Xml's Root node/ where to get data from
     confLoader conf = new confLoader("conf.xml", "config"); 

     System.out.println(conf.getDbElement("dataSource") );
     System.out.println(conf.getDbElement("dataSource") );
     System.out.println(conf.getDbElement("dataSource") );  // Fails 
...

负责构建 DOM 并从 ('getDbElement()') 解析的代码:

public class confLoader{

 DocumentBuilderFactory docBuilderFactory;
 DocumentBuilder docBuilder;
 Document doc;
 NodeList nList;

 public confLoader(String path, String XmlRoot){

    try {
            docBuilderFactory = DocumentBuilderFactory.newInstance();
            docBuilder = docBuilderFactory.newDocumentBuilder();
            doc = docBuilder.parse(new File(path));
            // normalize text representation
            doc.getDocumentElement().normalize();                
    nList = doc.getElementsByTagName(XmlRoot);

  } catch (Exception e) {
    e.printStackTrace();
  } 
}

public String getDbElement(String element) {

    Node nNode = nList.item(0); //  1st item/node - sql
    try {
        if (nNode.getNodeType() == Node.ELEMENT_NODE) {     /////  Line 36 - Problematic

            Element eElement = (Element) nNode;
            return (((Node) eElement.getElementsByTagName(element).item(0).getChildNodes().item(0)).getNodeValue());
        }
    } catch (Exception ex) {
        System.out.println("Error retrieving " + element + " :" + ex.getMessage());//Thread.dumpStack();
         ex.printStackTrace();
      }
    return "not available";
 }

}

给定代码的堆栈跟踪:

  jdbc:mysql://localhost:...
  java.lang.NullPointerException
  jdbc:mysql://localhost:...
  Error retrieving dataSource :null
  not available
  at exercise.confLoader.getDbElement(confLoader.java:36)
  at exercise.Exercise.main(Exercise.java:22)

      Line 36 : if (nNode.getNodeType() == Node.ELEMENT_NODE)

xml 解析完成了两次,第三次我尝试从 Xml 解析,我得到 NullPointerException。

4

3 回答 3

2

代码太多!此外,按需读取配置片段也不是很有用。依赖实例变量会使您的代码更难测试和理解,甚至在并发场景中可能不安全。你不需要所有那些类、方法和东西。这只是一个问题

public class Exercise {

    public static void main(String[] args) throws XPathExpressionException {

        XPath xpath = XPathFactory.newInstance().newXPath();
        InputSource in = new InputSource("res/config.xml");

        String user = xpath.evaluate("//sql/user/text()", in);
        String password = xpath.evaluate("//sql/password/text()", in);
        String path = xpath.evaluate("//sql/dataSource/text()", in);

        Sql sql = new Sql(path, user, password);
    }

}

您可以选择使您的代码更复杂一点,方法是将所有配置存储在 中Map<String, String>,但实际上您最好使用通用 API,例如Properties,它能够从 XML 加载。

于 2012-09-25T11:45:42.603 回答
1

通过从构建路径中删除 gnujaxp.jar 解决了问题。

于 2012-10-02T01:35:25.660 回答
0

首先,我建议您不要在一行上链接太多方法。将调用结构分成多行将增加可读性并简化调试。

例如,重写:

return (((Node) (eElement.getElementsByTagName("password").item(0).getChildNodes().item(0)).getNodeValue());

到:

NodeList rootEls = eElement.getElementsByTagName("password");
Node rootEl = rootEls.item(0)
NodeList children = rootEl.getChildNodes();
Node passEl = children.item(0);
return passEl.getNodeValue();

当您获得 NullPointerException 时,使用此代码,您可以从异常中的行号中提取更多信息。

其次,在这种情况下,查看用于 Java 的各种 XML 处理库并找到一个允许使用 XPath 的库可能很有用,另请参见:this tutorial on Xpath

我希望这有帮助。随时提出任何问题。

于 2012-09-25T11:26:04.907 回答