【问题标题】:parsing an XML with JAVA用 JAVA 解析 XML
【发布时间】:2014-02-24 15:05:55
【问题描述】:

我正在尝试解析 xml 文档的一些特定部分。我正在考虑将数据从分析部分中提取出来,我需要警告、错误、通过,并且我需要进入每个部分 () 并获取结果和结果级别以及例如此“错误”中的文本我需要获取错误级别和文本“错误”。

<document>
    <configuration>
    </configuration>
    <data>
    </data>
    <analysis warnings="5" errors="3" information="0" passed="false">
        <files>
        </files>
        <results>
            <form>
                <section number="0">
                    <result level="error">ERROR</result>
                    <result level="error">ERROR</result>
                    <result level="error">ERROR</result>
                    <result level="warning">Warning</result>
                    <result level="warning">Warning</result>
                </section>
                <section number="1">
                    <result level="warning">WARNING</result>
                </section>
                <section number="2">
                    <result level="warning">WARNING</result>
                    <result level="warning">WARNING</result>
                </section>
            </form>
        </results>
    </analysis>
</document>

我有以下代码:

public void ProcessXMLFromPath(String path) throws Exception
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document =  builder.parse(path);
        NodeList nodeList = document.getDocumentElement().getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
          Node node = nodeList.item(i);
          if (node instanceof Element) {
            System.out.println(node.getAttributes().toString());
            NodeList childNodes = node.getChildNodes();
            for (int j = 0; j < childNodes.getLength(); j++) {
              Node cNode = childNodes.item(j);

              if (cNode instanceof Element) {
                  System.out.println(cNode.getNodeName().toString()); 
                  if(cNode.getNodeName().toString() == "analysis")
                  {
                      String content = cNode.getLastChild().getTextContent().trim();
                      System.out.println(content);
                      //I thought this would print the children under the analysis section to the screen but I was mistaken. It does however make it to this point.
                  }
              }
            }

          }

        }
    }

我要打印到控制台的唯一内容是:

configuration
data
analysis

任何帮助将不胜感激!

【问题讨论】:

    标签: java parsing xml-parsing


    【解决方案1】:

    代码的几个问题:

    1. cNode.getNodeName().toString() == "analysis",与.equals 进行字符串比较
    2. analysisdocument 的直系后代(根据我们这里的 xml 片段),因此必须尽早检查。您的代码在 level 3 而不是 2 进行检查
    3. 您需要进一步深入分析以获得resultsformtext 节点。

    编辑: 基于 cmets,一种无需多个 for 循环的有效遍历方式就是递归,如下:

    public static void main(String[] args) throws ParserConfigurationException,
            SAXException, IOException {
        InputStream path = new FileInputStream("sample.xml");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(path);
        traverse(document.getDocumentElement());
    
    }
    
    public static void traverse(Node node) {
        NodeList list = node.getChildNodes();
        for (int i = 0; i < list.getLength(); i++) {
            Node currentNode = list.item(i);
            traverse(currentNode);
    
        }
    
        if (node.getNodeName().equals("result")) {
            System.out.println("This -> " + node.getTextContent());
        }
    
    }
    

    结果如下:

    This -> ERROR
    This -> ERROR
    This -> ERROR
    This -> Warning
    This -> Warning
    This -> WARNING
    This -> WARNING
    This -> WARNING
    

    【讨论】:

    • 有没有办法让它逐行解析?现在它将错误和警告消息打印为一大块文本。
    • 无论如何你可以通过更新你的答案来告诉我吗?我试图迭代,但我一直在制作 for 循环并尝试向下分支,我知道它们必须是更好的方法。
    • @user1857654 用最有效的方式(通过递归)更新了上面的代码,并描述了你遍历的节点
    • 老大,谢谢!效果很好,看起来比我正在做的 for 循环要好。
    • @user1857654 不客气,是的,这是一种更好的方法。
    【解决方案2】:

    对于这三个(configurationdataanalysis)中的每一个,获取它们的子节点并向下钻取,直到找到您的错误(即您的 result 标记)。您将在analysis 下方找到这些内容(但不在其正下方)。所以你可以从analysis向下钻取。

    【讨论】:

    • 如何去做呢?比如我如何深入到每个部分和小节?
    • 与您从documentanalysis 的方式相同。致电getChildNodes()
    • 有更好/更清洁的方法吗?现在我看到我会有几个嵌套的 for 循环,它看起来真的很脏。
    • 另一种方法是使用另一个解析器 - 例如SAX 解析器或 StAX 解析器。如果您只对这些result 错误感兴趣,也许这对您的情况会更好。您现在正在使用 DOM 解析器。
    猜你喜欢
    • 2012-11-17
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多