如何提高使用VTD-XML和XPath查询xml文件的性能?

时间:2019-04-15 14:01:59

标签: java xml vtd-xml

我正在查询大小约为1 MB(20k +行)的XML文件。我正在使用XPath来描述我想要获取的内容以及VTD-XML库来获取它。我认为我在性能方面存在一些问题。

问题是,我要对XML文件进行5k多次查询。检索所有值大约需要16-17秒。我想问你,这是正常的表现吗?我该如何改善?

我正在将VTD-XML库与AutoPilot导航方法结合使用,这给了我使用XPath的机会。实现如下:

private VTDGen vg = new VTDGen();
private VTDNav vn;
private AutoPilot ap = new AutoPilot();

public void init(String xml) {
    log.info("Creating document");
    xml = xml.replace("<?xml version=\"1.0\"?>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    byte[] bytes = xml.getBytes(StandardCharsets.UTF_8);
    vg.setDoc(bytes);
    try {
        vg.parse(true);
        vn = vg.getNav();
    } catch (ParseException e) {
        e.printStackTrace();
    }
    log.info("Document created");
}

public String parseXmlOrReturnNull(String query) {
    String xPathStringVal = null;
    try {
        ap.selectXPath(query);
        ap.bind(vn);
        int i = -1;
        while ((i = ap.evalXPath()) != -1) {
            xPathStringVal = vn.getXPathStringVal();
        }
    }catch (XPathEvalException e) {
        e.printStackTrace();
    } catch (NavException e) {
        e.printStackTrace();
    } catch (XPathParseException e) {
        e.printStackTrace();
    }
    return xPathStringVal;
}

我的xml文件具有特定的格式,它们分为许多部分-段,并且我对所有段的查询都是相同的(我正在循环查询)。例如xml的一部分:

<segment>
    <a>
        <b>value1</b>
        <c>
            <d>value2</d>
            <e>value3</d>
        </c>
    </a>
</segment>
<segment>
    <a>
        <b>value4</b>
        <c>
            <d>value5</d>
            <e>value6</d>
            <f>value6</d>
        </c>
    </a>
</segment>
...

如果我想在第一段中获取value1,我正在使用查询:

//segment[1]/a/b

第二部分中的值4

//segment[2]/a/b

直觉说了几件事:在我的方法中,每个查询都是独立的(它对其他查询一无所知),这意味着当我要查询它时,我的迭代器AutoPilot总是从文件的开头开始。

我的问题是:有什么方法可以在处理段的开头设置AutoPilot?当我完成查询时,将AutoPilot移至下一个段?我认为,如果我的方法不是从头开始而是从指定点开始搜索值,它将更快。

另一种方法是将xml文件分成小xml文件(一个xml文件=一个段)并查询这些小xml文件。

您觉得家伙如何?预先感谢

1 个答案:

答案 0 :(得分:0)

次要的:由于UTF-8是默认编码,因此不需要替换。仅当存在 编码时,才需要将其修补为UTF-8。

XPath只能执行一次,不能从[0]开始到下一个索引。

如果需要列表表示形式,可以将JAXB与注释一起使用。

基于事件的原始分析而没有 DOM对象可能是最好的(SAXParser)。

Load Balancer