在 Java 中读取复杂的 XML 文件



我能够在java中读取许多类型的xml文件。 但是今天我得到了一个XML文件,无法读取其详细信息。

<ENVELOPE>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>1</BILLREF>
<BILLPARTY>Party1</BILLPARTY>
</BILLFIXED>
<BILLCL>-10800.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-10800.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>2</BILLREF>
<BILLPARTY>Party2</BILLPARTY>
</BILLFIXED>
<BILLCL>-2000.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-2000.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>3</BILLREF>
<BILLPARTY>Party3</BILLPARTY>
</BILLFIXED>
<BILLCL>-1416.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-1416.00</BILLFINAL>
<BILLDUE>31-Jul-2017</BILLDUE>
<BILLOVERDUE>0</BILLOVERDUE>
</ENVELOPE>

我正在使用此代码读取 xml 文件。我能够读取标签内的数据<BILLFIXED>但无法读取标签外的数据,如<BILLFINAL><BILLDUE>等。>

try {
File fXmlFile = new File("filepath");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);

doc.getDocumentElement().normalize();
NodeList billNodeList = doc.getElementsByTagName("ENVELOPE");
for(int i=0;i<billNodeList.getLength();i++){
Node voucherNode = billNodeList.item(i);
Element voucherElement = (Element) voucherNode;
NodeList nList = voucherElement.getElementsByTagName("BILLFIXED");

for (int temp = 0; temp < nList.getLength(); temp++) {
Node insideNode = nList.item(temp);
Element voucherElements = (Element) insideNode;
System.out.println(voucherElements.getElementsByTagName("BILLDATE").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLREF").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLPARTY").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLFINAL").item(0).getTextContent());
System.out.println(voucherElements.getElementsByTagName("BILLOVERDUE").item(0).getTextContent());
}
}


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

我正在尝试所有可能的方式,我知道这一点,但目前我无法找到任何解决方案。 如果有人有任何解决方案,请与我分享。

一种方法是"修复"XML使其结构更完善,例如:

// Fix the XML
Element envelopeElem = doc.getDocumentElement();
List<Node> children = new ArrayList<>();
for (Node child = envelopeElem.getFirstChild(); child != null; child = child.getNextSibling())
children.add(child);
Element billElem = null;
for (Node child : children) {
if (child.getNodeType() == Node.ELEMENT_NODE && "BILLFIXED".equals(child.getNodeName()))
envelopeElem.insertBefore(billElem = doc.createElement("BILL"), child);
if (billElem != null)
billElem.appendChild(child);
}

该代码基本上是在遇到<BILLFIXED>元素时创建一个新的<BILL>元素作为<ENVELOPE>的子元素,然后将所有后续节点移动到<BILL>元素中。

结果是 DOM 树中的 XML 看起来像这样1,这应该更容易处理:

<ENVELOPE>
<BILL>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>1</BILLREF>
<BILLPARTY>Party1</BILLPARTY>
</BILLFIXED>
<BILLCL>-10800.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-10800.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
</BILL>
<BILL>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>2</BILLREF>
<BILLPARTY>Party2</BILLPARTY>
</BILLFIXED>
<BILLCL>-2000.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-2000.00</BILLFINAL>
<BILLDUE>1-Jul-2017</BILLDUE>
<BILLOVERDUE>30</BILLOVERDUE>
</BILL>
<BILL>
<BILLFIXED>
<BILLDATE>1-Jul-2017</BILLDATE>
<BILLREF>3</BILLREF>
<BILLPARTY>Party3</BILLPARTY>
</BILLFIXED>
<BILLCL>-1416.00</BILLCL>
<BILLPDC/>
<BILLFINAL>-1416.00</BILLFINAL>
<BILLDUE>31-Jul-2017</BILLDUE>
<BILLOVERDUE>0</BILLOVERDUE>
</BILL>
</ENVELOPE>

1) XML 已重新格式化以方便人类阅读,即它已被重新缩进。

它不是结构良好的XML。在您的<envelope>标签中,没有任何内容可以指示构成"账单"的每组六个属性的开头。您通常希望每个人都有一个<bill></bill>标签来包含它们。这会混淆解析器...

根据示例 XML,它有 3 条记录的数据。但每条记录都没有任何分隔。看起来每个字段数据都填充到 XML 标记中并写入文件中。

我建议有 2 个可能的选择

  1. 基于JAVA:正如Andreas所建议的那样,读取文件内容并为每条记录添加一个根标记,这将提供有限的XML结构,然后更容易处理。当输入文件较大时,性能影响可能会增加。
  2. 基于转换:尝试STX转换,它将结构转换为所需的格式XML甚至平面文件。然后处理会更简单

最新更新