<RmtInf>
<Strd>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Cd>CINV</Cd>
</CdOrPrtry>
</Tp>
<Nb>3501870</Nb>
</RfrdDocInf>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Prtry>AGJ</Prtry>
</CdOrPrtry>
</Tp>
<Nb>10090187000155438</Nb>
</RfrdDocInf>
<RfrdDocAmt>
<DuePyblAmt Ccy="SEK">5453.29</DuePyblAmt>
</RfrdDocAmt>
</Strd>
<Strd>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Cd>CINV</Cd>
</CdOrPrtry>
</Tp>
<Nb>160120</Nb>
</RfrdDocInf>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Prtry>AGJ</Prtry>
</CdOrPrtry>
</Tp>
<Nb>10090187000155438</Nb>
</RfrdDocInf>
<AddtlRmtInf>/ARI/</AddtlRmtInf>
</Strd>
</RmtInf>
while (ap.evalXPath() != -1)
{
if (vn.toElement(VTDNav.FIRST_CHILD, "AmtDtls")) {
do {
amtDetails = getXpathValue(vn, ".//TxAmt/Amt/text()");
// System.out.println("amtDetails:::" + amtDetails);
if (amtDetails != null)
creditNotification.setAmount(new BigDecimal(amtDetails));
} while (vn.toElement(VTDNav.NEXT_SIBLING, "AmtDtls"));
}
vn.push();
// System.out.println("transIndex::" + transIndex);
ap1.selectXPath("/Document/BkToCstmrDbtCdtNtfctn/Ntfctn/Ntry/NtryDtls/TxDtls[" + transIndex
+ "]/RmtInf/Strd");
while (ap1.evalXPath() != -1) {
// System.out.println("sCount::::"+sCount);
custInvType = getXpathValue(vn, "RfrdDocInf[1]/Tp/CdOrPrtry/Cd/text()");
// System.out.println("custInvType:::" + custInvType);
creditNotificationFlag = false;
if (custInvType != null
&& custInvType.equalsIgnoreCase(IBS2BankConstants.TYPE_DEBITCREDITNOTIFICATION_CINV)) {
kidNmbr = getXpathValue(vn, "RfrdDocInf[1]/Nb/text()");
// System.out.println("\tskidNmbr::::" + kidNmbr);
// added as an required by IBS team
creditNotification.setMemo3(kidNmbr);
if (kidNmbr != null) {
creditNotification.setKid(kidNmbr);
if (kidNmbr.matches("^\\d{18}")) {
creditNotification
.setCustomerNumber(IBS2BankUtility.getKidsCustomerNumber(kidNmbr));
// logger.debug("custNumber:::" +
// custNumber);
creditNotification.setInvoiceNumber(IBS2BankUtility.getKidsInvoiceNumber(kidNmbr));
// logger.debug("custInvoice:::" +
// custInvoice);
} else if (kidNmbr.matches("^\\d{10}")) {
creditNotification.setInvoiceNumber(IBS2BankUtility.getKidsInvoiceNumber(kidNmbr));
}
}
}
String prtryCodeType = getXpathValue(vn, "RfrdDocInf[2]/Tp/CdOrPrtry/Prtry/text()");
// System.out.println("prtryCodeType :::" +
// prtryCodeType);
if (prtryCodeType != null
&& prtryCodeType.equalsIgnoreCase(IBS2BankConstants.PROPRIETARY_CODE_AGJ)) {
// added as an required by IBS team
creditNotification.setMemo4(getXpathValue(vn, "RfrdDocInf[2]/Nb/text()"));
}
credNotificationList.add(creditNotification);
}
ap1.resetXPath();
vn.pop();
}
我更新了xml,代码Push()用于保存当前位置的状态,第二次使用是因为RmtInf
有多个Strd
,我想遍历它。现在上面的代码可以工作,但是解析xml文件大小为600 MB需要花费很多时间。
答案 0 :(得分:0)
首先,你的文档的嵌套级别非常深,如果你做了大量的xpath,我建议你打开VTDGen的set LC level方法并将其设置为5(默认为3)...
因为你的doc明显低于2GB的限制,考虑切换到标准的vtd-xml(你有大约1GB的内存吗?)。尽管它没有内存映射功能,但它可以更好地调整性能。
要选择更深层的索引级别,请调用VTDGen的selectLcDepth(int i)并将i设置为5.
我注意到的另一件事是你的代码
getXpathValue(vn, ".//TxAmt/Amt/text())
我建议你将选择xpath表达式逻辑移出xpath评估循环,而不是在循环之前的代码中进行xpath编译......它看起来像......
Autopilot ap_temp = new AutoPilot(vn);
ap_tmp.selectXPath("..//TxAmt/Amt/text()");
...
int i=-1;
while((i=ap.evalXPath())!=-1){
...
//amtDetails = getXpathValue(vn, ".//TxAmt/Amt/text()"); will be replaced by
amtDetails = getXpathValue(vn, ap_temp);
此外,如果amtDetails是一个字符串,你可以直接使用evalXPathToString()
这样的东西直接将输出转换为字符串......
你的代码有多个selectXPath,我怀疑杀死的性能,你应该尝试将它们带出循环...
我前一段时间写了一篇博客.. .https://ximpleware.wordpress.com/2015/10/12/performance-tuning/
推送和弹出的位置似乎是错误的。具体来说,push()应该在主逻辑中的代码之前立即...我很惊讶您的代码按照您的指示运行...您是否注意到有两个巨大的XPath评估循环相互嵌套?这看起来不太好......
总的来说,我认为你已经创建了一段代码,旨在以非常低效的方式运行。
这是我现在的建议......
期待您的想法和评论。
要使代码正常工作,你需要在循环中使用vtd-xml游标...我假设你也知道你需要在while循环中保持节点位置,以免影响xpath的正确性评价...
您的代码可能看起来像这样...
VTDNav vn = vg.getNav();
...
while (ap.evalXPath() != -1) {
if (vn.toElement(VTDNav.FIRSTCHILD)){
System.out.println(" node name ===>"+vn.toRawString(vn.getCurrentIndex()));
vn.toElement(VTDNav.PARENT);
}
}