有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有一个给定形式的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标记总数可能为200-400万,每个元素中都有其他标记。 可以看出,myGroupIDmyGroupValue标记对于不同的元素有重复的值

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

我试着用Stax parser with Iterator api [event based approach]。我学到的是,我必须检查所有标记,以检查event.getLocalNamemyGroupID还是myGroupValue,如果是,那么我必须使用我的逻辑来检查文件中已经解析的部分是否与当前元素的值相同

但是使用这种方法,我不必要地重复使用其他标记(除了myGroupIDmyGroupValue),这似乎是在浪费时间

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

更不用说,我对stax解析的知识为零甚至更少,今天才有机会学习它,我将使用java进行这种解析

提前感谢我们的建议

更新:

感谢大家的宝贵意见。现在,我正在使用Stax迭代器API来解决这个需求,它似乎运行得非常快。此外,代码使用的内存也是可以接受的~3mb,而我正在解析的文件的总大小是55mb。这样对我来说一切都很好

只有几件事仍然困扰着我:-XML包含leadingtraining空格和'-' character。当我们不解析文件,而是直接解析来自HTTPConnection的输入流的XML时,有什么建议可以消除它们吗

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


共 (1) 个答案

  1. # 1 楼答案

    为什么不使用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更快,内存需求仍然很小