我遇到了一个问题,试图解析一些XML文档以获得我需要的输出。
获取此示例XML:
<root>
<ZoneRule Name="After" RequiresApproval="false">
<Zone>
<WSAZone ConsecutiveDayNumber="1">
<DaysOfWeek>
<WSADaysOfWeek Saturday="false"/>
</DaysOfWeek>
<SelectedLimits>
</SelectedLimits>
<SelectedHolidays>
</SelectedHolidays>
</WSAZone>
</Zone>
</ZoneRule>
<ZoneRule Name="Before" RequiresApproval="false">
<Zone>
<WSAZone ConsecutiveDayNumber="3">
<DaysOfWeek>
<WSADaysOfWeek Saturday="true"/>
</DaysOfWeek>
<SelectedLimits>
</SelectedLimits>
<SelectedHolidays>
</SelectedHolidays>
</WSAZone>
</Zone>
</ZoneRule>
</root>
&#13;
我试图做的是能够忽略根标签(这在这里没有问题),并且对待每个&#34; ZoneRule&#34;作为自己的个体块。
一旦我将每个ZoneRule隔离,我需要提取所有节点和属性,以允许我创建一个字符串来查询数据库以检查它是否存在(这部分也在工作)。
我遇到的问题是,在我的代码中,我无法将每个单独的ZoneRule块分开,出于某种原因,它被一起处理。
我的示例代码如下:
public String testXML = "";
int andCount = 0;
public void printNote(NodeList nodeList) {
for (int count = 0; count < nodeList.getLength(); count++) {
Node tempNode = nodeList.item(count);
// make sure it's element node.
if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
if (tempNode.hasAttributes()))) {
// get attributes names and values
NamedNodeMap nodeMap = tempNode.getAttributes();
for (int i = 0; i < nodeMap.getLength(); i++) {
Node node = nodeMap.item(i);
if (andCount == 0) {
testXML = testXML + "XMLDataAsXML.exist('//" + tempNode.getNodeName() + "[./@" + node.getNodeName() + "=\"" + node.getNodeValue() + "\"]')=1 \n";
} else {
testXML = testXML + " and XMLDataAsXML.exist('//" + tempNode.getNodeName() + "[./@" + node.getNodeName() + "=\"" + node.getNodeValue() + "\"]')=1 \n";
}
andCount = andCount + 1;
}
}
if (tempNode.hasChildNodes()) {
// loop again if has child nodes
printNote(tempNode.getChildNodes());
}
}
}
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
try {
File file = new File("C:\\Test.xml");
DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = dBuilder.parse(file);
//System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
if (doc.hasChildNodes()) {
printNote(doc.getChildNodes());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(testXML);
}
&#13;
产生此输出(两个节点组合)。
XMLDataAsXML.exist('//ZoneRule[./@Name="After"]')=1
and XMLDataAsXML.exist('//ZoneRule[./@RequiresApproval="false"]')=1
and XMLDataAsXML.exist('//WSAZone[./@ConsecutiveDayNumber="1"]')=1
and XMLDataAsXML.exist('//WSADaysOfWeek[./@Saturday="false"]')=1
and XMLDataAsXML.exist('//ZoneRule[./@Name="Before"]')=1
and XMLDataAsXML.exist('//ZoneRule[./@RequiresApproval="false"]')=1
and XMLDataAsXML.exist('//WSAZone[./@ConsecutiveDayNumber="3"]')=1
and XMLDataAsXML.exist('//WSADaysOfWeek[./@Saturday="true"]')=1
我实际上是这样的(借口不完整的SQL语句):
XMLDataAsXML.exist('//ZoneRule[./@Name="After"]')=1
and XMLDataAsXML.exist('//ZoneRule[./@RequiresApproval="false"]')=1
and XMLDataAsXML.exist('//WSAZone[./@ConsecutiveDayNumber="1"]')=1
and XMLDataAsXML.exist('//WSADaysOfWeek[./@Saturday="false"]')=1
XMLDataAsXML.exist XMLDataAsXML.exist('//ZoneRule[./@Name="Before"]')=1
and XMLDataAsXML.exist('//ZoneRule[./@RequiresApproval="false"]')=1
and XMLDataAsXML.exist('//WSAZone[./@ConsecutiveDayNumber="3"]')=1
and XMLDataAsXML.exist('//WSADaysOfWeek[./@Saturday="true"]')=1
将要解析的XML并不总是如上所述,所以我不能使用硬编码的xPaths等 - 我需要动态循环遍历文档,寻找ZoneRule节点作为我的基础(我将动态生成此值基于收到的文件)然后提取所有必需的信息。
我完全乐于接受比上述尝试更好的方法。
非常感谢。
答案 0 :(得分:0)
在您的代码中,testXML
和andCount
在printNote
方法之外声明,并且在迭代期间不会被重置。
你从第一个ZoneRule开始,在第一个迭代期间生成正确的文本(让我们忘记递归),现在你移动到下一个ZoneRule,但是testXML包含整个生成的文本,而theCount则是大于0,所以你继续附上为下一个ZoneRule生成的文本。
您应该在for循环的每个iteriation的初始化时重置andCount和testXML。但是那时你会递归'儿童不能正确呈现。
所以要么你需要两个方法来处理顶层的ZoneRule元素而另一个用于它的子节点,或者更好,而不是将文本追加到共享变量,你应该重新设置你的方法,这样它们就会返回String值,然后就可以了在递归调用时正确地附加(使用或不使用新行或不使用)。