1

在网上大量研究之后,我决定使用 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>

请不要开始讨论结构和元素名称。我无法改变这一点。

我想编辑文件中所有匹配某个 xPath 表达式的元素值。当我为此使用 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>

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

谢谢你的帮助!

4

1 回答 1

2

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

 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"));
}
于 2015-08-16T19:58:53.280 回答