使用VTD-XML和Java修改xPath Expression在大型xml文件中找到的所有值

时间:2015-08-13 13:08:26

标签: java xml xpath vtd-xml

经过对网络的大量研究,我决定使用Java Api VTD-XML来组合巨大的xml文件,解析和编辑,以及xPath

要修改的XML文件是10 MB - 400 MB,如下所示:

<?xml version="1.0" encoding="ISO-8859-9"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Scheme.xsd">
<Book>
    <BookInfo>
        <Novel>
            <NovelTitle>abc</NovelTitle>
            <Author>def</Author>
            <Address>
                <LastName>ghi</LastName>
                <FirstName>jklm<FirstName>
            </Address>
            <Address>
                <LastName>opqr</LastName>
                <FirstName>stuv</FirstName>
            </Address>
            <Customer>
                <CustomerNumber>1000</CustomerNumber>
                <Address>
                    <LastName>wxy</LastName>
                    <FirstName>zzzz</FirstName>
                </Address>
                <Address>
                    <LastName>aaaaa</LastName>
                    <FirstName>bbbb</FirstName>
                </Address>
            </Customer>
            .
            .
            .
        </Novel>
    </BookInfo>
</Book>

请不要开始讨论结构和元素名称。我不能改变它。

我想编辑File中与特定xPath Expression匹配的所有匹配项的元素值。 当我使用VTD XML和XPath时,在结果文档中只有一个元素值被正确更改。 我的代码:

    static VTDGen vg = new VTDGen();
static String inFile = "books.xml";
static XMLModifier xm = new XMLModifier();

public static void main(String[] args) throws Exception{

    getNodesFromDocument();
}

private static void getNodesFromDocument() throws ParseException, NavException, XPathParseException, XPathEvalException, Exception {
    int result;
    AutoPilot ap = new AutoPilot();
    ap.selectXPath("//Address[LastName='ghi']/FirstName/text()");
    if (vg.parseFile(inFile,true)){
        VTDNav vn = vg.getNav();
        ap.bind(vn);
        while((result = ap.evalXPath())!=-1){

            //System.out.println(vn.getText() + vn.toString(result));
            modifyNodes(vn, result);

        }
    }
    xm.output(new FileOutputStream("resultbooks.xml"));

}

private static void modifyNodes(VTDNav vn, int line) throws Exception{
    // instantiate VTDGen and XMLModifier
    xm.bind(vn);
        // update the text content

        if (line!=-1){
            xm.updateToken(line,"TestValue");
        }
}
}

我想在文档中编辑// Address [LastName ='ghi'] / FirstName / text()的所有值,所以

jkl
.
.
.

getNodesFromDocument()中的while循环正确显示所有值,但并非所有值都被修改。只有一个

                    <LastName>ghi</LastName>
                <FirstName>TestValue<FirstName>

出现在输出文件中。你能帮我找到问题的解决方案吗?代码什么错了?为什么输出中只有一个修改后的值?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

textValue只出现一次的原因是因为XMLModifier的绑定做了很多初始化和状态清理,它实际上消除了之前发生的任何更新/删除...你需要做的就是不绑定它每次使用私有方法&#34; modifyNode,&#34;而是将绑定移动到主...它将工作...请参阅下面的代码

 static VTDGen vg = new VTDGen();
 static String inFile = "c:\\xml\\kepler.xml";
 static XMLModifier xm = new XMLModifier();

/**
 * @param args
 */
public static void main(String[] args) throws ParseException, NavException, XPathParseException, XPathEvalException, Exception{
    // TODO Auto-generated method stub
     int result;
        AutoPilot ap = new AutoPilot();
        ap.selectXPath("//Address[LastName='ghi']/FirstName/text()");
        if (vg.parseFile(inFile,true)){
            VTDNav vn = vg.getNav();
            ap.bind(vn);xm.bind(vn);
            while((result = ap.evalXPath())!=-1){

                //System.out.println(vn.getText() + vn.toString(result));
                xm.updateToken(result,"TestValue");

            }
        }
        xm.output(new FileOutputStream("c:\\xml\\resultbooks.xml"));
}