在解析XML时将子节点与控制值进行比较

时间:2012-10-09 21:04:05

标签: java xml xml-parsing

我有一个这样组织的XML文件,每个节点下的项目总是按字母顺序排列:

<xml>
    <node id="2">
        <jack>Jack wrote this.</jack>
        <john>John wrote this.</john>
    </node>

    <node id="4">
        <jack>Jack wrote this.</jack>
        <jill>Jill wrote this.</jill>
    </node>

    <node id="9">
        <jack>Jack wrote this.</jack>
        <james>James wrote this.</james>
        <jill>Jill wrote this.</jill>
        <john>John wrote this.</john>
    </node>
</xml>

如您所见,并非所有名称都在每个节点下。例如,在<node id="4">中,约翰和詹姆斯没有写任何东西。对于上面的例子,我希望我的程序返回这样的东西:

James did not write 2, 4
Jill did not write 2
John did not write 4

我需要跟踪谁没有写什么。我目前正在解析这样的文档:

private static String getTagValue(final Element element)
{
    String theId="";
    if (element.getTagName().startsWith("node")){

        theId = element.getAttribute("id");
        return theId;
    }
    return theId;
}


private static void readXML(String fileName){

    for (int index = 0; index < nodeList.getLength(); index++){

                Node node = nodeList.item(index);
                Element element = (Element) node;

                if (node.getNodeType() == Node.ELEMENT_NODE){

                    // This prints the node id
                    if(getTagValue(element)!=""){
                        System.out.println(getTagValue(element)+" = I am the node id number!");
                    }

                    // This prints the name
                    else{
                        System.out.println(element.getTagName()+" = I am the name!");
                    }
                }
            }
}

我想要做的是以某种方式将每个节点下的元素与包含所有名称的“控件”列表进行比较,如果它不包含名称,则返回名称及其父节点。

实际上,我正在处理的XML要大得多,因此性能很重要,但概念是一样的。任何帮助都会很棒。

2 个答案:

答案 0 :(得分:1)

保持两套。一个是所有名称的主集(A)。第二个是你在每次迭代中建立的一组,回答问题的人(B)。然后,没有回答的人将是A - B,您可以使用Collection#removeAll(Collection c)执行此操作:

A.removeAll(B);

你提到你想在一行中打印出一个人没有回答的答案。为此,您可以维护一个地图(Map<String, List<Integer>>),将人名称映射到他们未回答的问题编号列表中。您可以通过在一次迭代结束时检查A.removeAll(B)的结果来完成此操作。

因此,一旦完成所有节点的循环,您最终会得到一个地图,该地图为您提供与他们未回答的问题列表相关联的每个名称。然后,您可以遍历此地图并打印出您需要的内容。

答案 1 :(得分:0)

从功能角度来看,我认为功能可能如下:

  • 对于每个节点节点获取xml文件中的所有子节点
  • 将每个子节点的名称与控件样本节点名称进行比较
  • 如果节点的名称匹配,则打破子循环
  • 如果名称不匹配,直到控制组的for循环完成,则找不到控制组的print语句名称