【问题标题】:Java DOM parser not parsing one line XMLJava DOM 解析器不解析一行 XML
【发布时间】:2013-04-23 08:24:54
【问题描述】:

我有如下 单行 xml 文件(没有缩进和换行)

    <?xml version="1.0" encoding="UTF-8"?>
    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03 
camt.054.001.03.xsd">
    <BkToCstmrDbtCdtNtfctn><GrpHdr><MsgId>0000000006</MsgId>
<CreDtTm>2013-04-
    16T14:38:00</CreDtTm>
</GrpHdr>
</BkToCstmrDbtCdtNtfctn></Document>

我正在使用这个 java DOM 解析器程序来解析和检索值

import java.io.File;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class GetNodeValues {
    static String value = null;
    static ArrayList alist = null;

    /****************** GET XPATH FOR EACH TAG **************************************/

    public static String getXPath(Element elemnt) {
        String xpath = null;
        String curNode = elemnt.getNodeName();
        ArrayList<String> al = new ArrayList<String>();
        al.add(curNode);
        // al.add(parNode);
        while (!elemnt.getParentNode().getNodeName().equals("#document")) {
            al.add(elemnt.getParentNode().getNodeName());
            elemnt = (Element) elemnt.getParentNode();
        }

        for (int i = al.size() - 1; i >= 0; i--) {
            xpath = xpath + "/" + al.get(i);
        }
        return xpath.replaceAll("null", "");
    }

    /******************************************************************************************/

    /**************************** GET TAG NAMES AND VALUES ***********************/

    public static ArrayList getValues() {
        try {

            alist = new ArrayList();
            String xmlFile = "C:/Users/Administrator/Desktop/sample2.xml";
            File file = new File(xmlFile);
            if (file.exists()) {

                // Create a factory
                DocumentBuilderFactory factory = DocumentBuilderFactory
                        .newInstance();
                // Use the factory to create a builder
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse(xmlFile);

                doc.getDocumentElement().normalize();

                // Get a list of all elements in the document
                NodeList list = doc.getElementsByTagName("*");

                for (int i = 0; i < list.getLength(); i++) {
                    // Get element
                    Element element = (Element) list.item(i);
                    String nodnam = element.getNodeName();


                    if (element.getChildNodes().getLength() > 0) // then it has
                                                                    // text
                    {
                        String val = element.getChildNodes().item(0)
                                .getNodeValue();
                        if (val.startsWith("\n")) { // Discarding pseudo nodes

                        } else {
                            value = nodnam + " > " + val + " > "
                                    + getXPath(element); // print node names and
                                                            // values
                            System.out.println(value);
                            alist.add(value);
                        }
                    }
                }
            } else {
                System.out.print("File not found!");
            }
        } catch (Exception e) {
            System.exit(1);
        }

        return alist;
    }

    /********************************************************************************************/

    /************************** MAIN METHOD **********************************************/
    public static void main(String[] args) {
        System.out.println(getValues());

    }
}

而且它不打印任何值。但是,如果我编辑 xml 文件并像这样添加缩进和新行

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.054.001.03 camt.054.001.03.xsd">
    <BkToCstmrDbtCdtNtfctn>
        <GrpHdr>
            <MsgId>0000000006</MsgId>
            <CreDtTm>2013-04-16T14:38:00</CreDtTm>
        </GrpHdr>
    </BkToCstmrDbtCdtNtfctn>
</Document>

然后我得到如下输出

MsgId > 0000000006 > /Document/BkToCstmrDbtCdtNtfctn/GrpHdr/MsgId
CreDtTm > 2013-04-16T14:38:00 > /Document/BkToCstmrDbtCdtNtfctn/GrpHdr/CreDtTm

所以问题是我不能编辑每个 xml 文件。要处理的文件很大。我在 java dom 解析器中遗漏了什么吗?我所需要的是程序应该解析和打印没有缩进和新行的 xml 文件的值....

【问题讨论】:

    标签: java xml dom xml-parsing


    【解决方案1】:

    注意这样做:

    } catch (Exception e) {
         System.exit(1);
    }
    

    您隐藏了异常,无法看到真正的问题。 至少打印堆栈跟踪,例如:

    } catch (Exception e) {
         e.printStackTrace();
         System.exit(1);
    }
    

    在这种情况下,String val = element.getChildNodes().item(0).getNodeValue(); 中的 var 可以为空。因此,使用以下修复程序应该可以解决此问题:

    String val = element.getChildNodes().item(0).getNodeValue();
    if (val != null) {
       if (val.startsWith("\n")) { // Discarding pseudo nodes
       } else {
           value = nodnam + " > " + val + " > "
                + getXPath(element); // print node names and
                                    // values
           System.out.println(value);
           alist.add(value);
      }
    }
    

    【讨论】:

    • 非常感谢 Dan,添加 e.printStackTrace() 后,我得到了 NullPointerException。然后我按照您的建议更改了代码,现在它可以正常工作了。再次感谢..
    【解决方案2】:

    除了导致 NPE 的实际问题外,我认为此时您的代码存在 3 个不同的问题:

      } catch (Exception e) {
         System.exit(1);
      }
    

    第一个问题(如@dan 所述)是您没有打印堆栈跟踪。

    第二个问题是你正在捕捉Exception。在大多数情况下,这是一个坏主意,因为您最终会捕获各种意外异常……除了您可能期望的任何异常。最好只捕获您期望并在那时可以处理的异常。其余的应该被允许传播。

    第三个问题是您正在调用System.exit,这似乎是一种实用方法。出于以下几个原因,这是一个坏主意:

    • 在一个方法中退出将使该方法难以在其他情况下使用......在这些情况下,退出是错误的做法。

    • 任何调用 System.exit 的方法都很难进行单元测试。如果您不采取措施避免它(例如,使用可以“模拟”该调用的模拟框架),该方法将导致运行单元测试的 JVM 立即停止。

    在我看来,编写该代码的正确方法是:

    1. 将任何必要的throws 子句添加到getValues() 方法声明中,并且
    2. try ... catch 放在main 方法中...当然还有一些代码来输出或记录异常堆栈跟踪。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-24
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 2012-11-18
      相关资源
      最近更新 更多