【问题标题】:How to parse xml using vtd-xml without hardcoding attr name?如何使用 vtd-xml 解析 xml 而无需硬编码 attr 名称?
【发布时间】:2017-02-08 11:41:04
【问题描述】:

这是我的示例 XML 文件,实际大小超过 2gb。使用 vtd-xml 我已经实现了这么多:

当前代码:

https://gist.github.com/shadow-fox/21d1d4f30cbed0909f403c3ac0e1fa4d

public void reader() throws IOException, ParseException, NavException, XPathParseExceptionHuge, NavExceptionHuge,
            XPathEvalExceptionHuge {
        VTDGenHuge vg = new VTDGenHuge();
    if (vg.parseFile("sku_extract_main.xml",true,VTDGenHuge.MEM_MAPPED)) {
        VTDNavHuge vnh = vg.getNav();
        AutoPilotHuge aph = new AutoPilotHuge(vnh);
        aph.selectElementNS("*", "*");
        int i = 0;
        while (aph.iterate()) {
            int t = vnh.getText();
            if (t != -1) {
                System.out.println(vnh.toString(vnh.getCurrentIndex()) + "|||" + vnh.toNormalizedString(t));
                i++;
            }
        }
    }
}

当前结果:

PVAL|||298374234
PVAL|||1231
PVAL|||brown
PVAL|||medium
PVAL|||7
PVAL|||solid
PVAL|||brown

我想要什么:

Sku_ID|||298374234
LotNum|||1231
COLOR|||brown
WIDTH|||medium
SIZE|||7
Pattern|||solid
Color Family|||brown

示例 xml:

<?xml version="1.0" encoding="UTF-8" ?>
<RECORDS>
  <RECORD>
    <PROP NAME="Sku_ID">
      <PVAL>298374234</PVAL>
    </PROP>
    <PROP NAME="LotNum">
      <PVAL>1231</PVAL>
    </PROP>
    <PROP NAME="COLOR">
      <PVAL>brown</PVAL>
    </PROP>
    <PROP NAME="WIDTH">
      <PVAL>medium</PVAL>
    </PROP>
    <PROP NAME="SIZE">
      <PVAL>7</PVAL>
    </PROP>
    <PROP NAME="Pattern">
      <PVAL>solid</PVAL>
    </PROP>
    <PROP NAME="Color Family">
      <PVAL>brown</PVAL>
    </PROP>
  </RECORD>
</RECORDS>

而且我不想硬编码attr 名称。我想在访问它们时取回它们。我该怎么做?

【问题讨论】:

    标签: java xml parsing vtd-xml


    【解决方案1】:

    下面是我编辑的代码以打印出 attr 名称和值...它是基于 xpath...

    public static void main(String s[]) throws Exception{
         VTDGenHuge vg = new VTDGenHuge();
            if (vg.parseFile("d:\\xml\\sku_extract_main.xml",true,VTDGenHuge.MEM_MAPPED)) {
                VTDNavHuge vnh = vg.getNav();
                AutoPilotHuge aph = new AutoPilotHuge(vnh);
                AutoPilotHuge aph2 = new AutoPilotHuge(vnh);
                aph.selectElementNS("*", "*");
                aph2.selectXPath("@*");
                int i = 0;
                while (aph.iterate()) {
                    System.out.println(vnh.toString(vnh.getCurrentIndex()));
                    int t = vnh.getText();
                    if (t != -1) {
                        System.out.println(vnh.toString(vnh.getCurrentIndex()) + "|||" + vnh.toNormalizedString(t));
                        i++;
                    }
    
    // below is the my addition
    // it basically evaluates the attribute axis
    // push pop ensure that the node iteration of the outer while loop
    // is consistent
    // resetXPath is key here, without it, xpath will not work except for the
    // first node returned by aph.iterate()
                    vnh.push();
    
                    while((i=aph2.evalXPath())!=-1){
                        System.out.println(" attr name "+vnh.toString(i));
                        System.out.println("attr val   "+vnh.toString(i+1));
                    }
                    aph2.resetXPath();
                    vnh.pop();
                }
    }
    

    【讨论】:

    • 能否请您添加 cmets 在做什么? vnh.toNormalizedString(t) 这给了我 attr 的值,例如。 298374234 ,但仅在 if 范围内,但不在抛出 IndexOutOfBoundsException 的 while 范围内。 vnh.toString(i+1) 给了我属性的名称,例如。 Sku_ID。
    • indexoutofBoundsException 是什么意思?
    • 关于 IndexOutOfBoundsException 是我尝试在 while 范围内提取 attr 值的地方,即 vnh.toNormalizedString(t)。
    • t = vnh.getText(); vnh.toNormalizedString(t) 这是该节点的实际值。
    • 这看起来根本不像属性,你指的是那个文本值吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    相关资源
    最近更新 更多