解析巨大的xml文件以从子标记中获取不同的值 - 需要最佳方法建议

时间:2013-12-18 20:52:20

标签: java xml xml-parsing stax

我有一个给定表格的xml。

 <myData>
    <myElement>
            <myGroupID>ID1</myGroupID>
            <myGroupValue>value1</myGroupValue>
    </myElement>
    <myElement>
            <myGroupID>ID2</myGroupID>
            <myGroupValue>value2</myGroupValue>
    </myElement>
    <myElement>
            <myGroupID>ID3</myGroupID>
            <myGroupValue>value3</myGroupValue>
    </myElement>
        <myElement>
            <myGroupID>ID4</myGroupID>
            <myGroupValue>value4</myGroupValue>
    </myElement>
        <myElement>
            <myGroupID>ID1</myGroupID>
            <myGroupValue>value1</myGroupValue>
    </myElement>
    <myElement>
            <myGroupID>ID2</myGroupID>
            <myGroupValue>value2</myGroupValue>
    </myElement>
    <myElement>
            <myGroupID>ID3</myGroupID>
            <myGroupValue>value3</myGroupValue>
    </myElement>
        <myElement>
            <myGroupID>ID4</myGroupID>
            <myGroupValue>value4</myGroupValue>
    </myElement>
<myData>    

文件中myElement个标签的总数可以是2-4百万,每个元素中还有其他标签。 可以看出,myGroupIDmyGroupValue标记具有不同元素的重复值。

我的要求是获得myGroupIDmyGroupValue标记的不同值。

我试图使用Stax parser with Iterator api [event based approach]。我学到的是,我必须通过所有标签检查event.getLocalNamemyGroupID还是myGroupValue,如果是,那么我将不得不使用我的逻辑检查文件的已解析部分是否具有任何值作为当前元素的值。

但是使用这种方法,我不必再遍历其他标签[myGroupIDmyGroupValue除外],这似乎是浪费时间。

知道如何直接跳转到元素中具有特定名称的标签吗?

更不用说我对stax解析有0甚至更少的知识,并且今天有机会学习它,我将使用java进行解析。

提前感谢我们提出的建议。

更新

感谢大家的宝贵意见。现在,我正在使用Stax Iterator API来满足要求,它似乎工作得非常快。此外,代码使用的内存也是可接受的~3mb,而我正在解析的文件的总大小为55mb。因此它对我有利。

一些仍困扰着我的事情: - XML包含leadingtraining个空格以及'-' character。有什么建议我们如何在不解析文件时解除它们,而是直接解析来自HTTPConnection的输入流的XML?

我没有选择在这里获得更好的XML [没有leadingtrailing spaces以及'-' character],因为我收到的XML实际上就是来自另一个系统的服务,他们还没有准备好修改他们的代码来满足我们系统的要求。

1 个答案:

答案 0 :(得分:0)

为什么不使用SAX? http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

public void startElement(....) {
    if (qName.equalsIgnoreCase("myElement")) {
        //do stuff, inElement = true, prepare new element...
    }

    else if (qName.equalsIgnoreCase("MYGROUPID") && inElement) {
        //do stuff
    }

    else if (qName.equalsIgnoreCase("MYGROUPVALUE") && inElement) {
        //do stuff
    }

类似地,在endElement()中,当找到“myElement”右括号时,你应该将inElement切换为false并使用当前元素中的groupId和groupValue存储或执行任何其他操作。这是最好的方式,速度非常快 - 甚至比Stax更快,内存需求仍然很少。