簡體   English   中英

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

[英]How to improve performance of querying xml file with VTD-XML and XPath?

我正在查詢大小約為1 MB(20k +行)的XML文件。 我正在使用XPath來描述我想要的內容和VTD-XML庫來獲取它。 我認為我在性能方面存在一些問題。

問題是,我正在對XML文件進行大約5k +查詢。 檢索所有值大約需要16-17秒。 我想問你,這個任務是否正常? 我怎么能改進它?

我正在使用帶有AutoPilot導航方法的VTD-XML庫,這讓我有機會使用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

等等

Intuition說了一些事情:在我的方法中,每個查詢都是獨立的(它對其他查詢一無所知),這意味着當我想查詢它時,AutoPilot,我的迭代器總是從文件的開頭開始。

我的問題是:有沒有辦法在處理段開始時設置AutoPilot? 當我完成查詢后,將AutoPilot移至下一個細分市場? 我認為如果我的方法不是從頭開始搜索值,而是從指定點開始搜索它會更快。

另一種方法是將xml文件分成小的xml文件(一個xml文件=一個段)並查詢那些小的xml文件。

你們覺得怎么樣? 提前致謝

Minor:不需要替換,因為UTF-8是默認編碼; 只有當一個編碼,一個需要它修補為UTF-8。

XPath應該只執行一次,不能從[0]開始到下一個索引。

如果需要List表示,可以使用帶注釋的JAXB。

基於事件的原始解析沒有 DOM對象可能是最好的(SAXParser)。

Handler handler = new org.xml.sax.helpers.DefaultHandler {
    @Override
    public void startElement(String uri, 
        String localName, String qName, Attributes attributes) throws SAXException {
    }

    @Override
    public void endElement(String uri, 
        String localName, String qName) throws SAXException {
    }

    @Override
    public void characters(char ch[], int start, int length) throws SAXException {
    }
};
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
InputStream in = new ByteArrayInputStream(bytes);
parser.parse(in, handler);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM