我需要解析一个xml文件,xml文件的结构如下所示:<Response>
<Object>
<Element>ID</Element>
<Element>XM</Element>
<Element>GMS</Element>
<Element>XB</Element>
</Object>

<Records> <Record>
<Element>GMS</Element>
<Value></Value>
</Record>
<Record>
<Element>ID</Element>
<Value>0011f887252346818a59fedffe6d7821
</Value>
</Record>
<Record>
<Element>XM</Element>
<Value>李明</Value>
</Record>
<Record>
<Element>XB</Element>
<Value>男</Value>
</Record>
<Record>
<Element>GMS</Element>
<Value>1111111111111111111</Value>
</Record>
<Record>
<Element>ID</Element>
<Value>0015224632e9476aaa8f419dcfc222b9
</Value>
</Record>
<Record>
<Element>XM</Element>
<Value>柳眉</Value>
</Record>
<Record>
<Element>XB</Element>
<Value>女</Value>
</Record>
          </Records>
<Response>其中<Object>中的内容是每一个人所具有的属性,<Records>里面的内容是每个人对应属性的数值。
然后再对其进行修改操作,我原来使用的是dom4j,但对于大数据量的xml文件操作时就会出现内存溢出错误。因此我现在换用了SAX来解析,因为SAX是事件触发的,遇到换行或者空白时也会触发void characters(char ch[], int start, int length),解析出好多无关的比如"\n"的字符,怎样只获取到数值内容忽略掉无关内容,比如对于后一条记录获取到如下内容:
GMS
1111111111111111111
ID
0015224632e9476aaa8f419dcfc222b9
XM
柳眉
XB

我获取到字符内容后还要进行判断修改操作,如何判断获取到的某一项内容,比如GMS对应的数值内容为空呢。我原来是将characters()方法 中获取到的字符内容放在List中,但我发现里面的无关内容太多,并且当某一项为空时List里面并没有存放相应的null或者" "。处理30M以上的xml如果不用sax,还有没有其他的方法。这个问题已经困扰我四五天了,一直没解决掉,还请大家多帮忙、多指教啊。

解决方案 »

  1.   

    import java.io.FileReader;
    import java.io.IOException;import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLEventReader;
    import javax.xml.stream.XMLStreamReader;
    import javax.xml.stream.XMLStreamException;import javax.xml.stream.events.XMLEvent;
    import javax.xml.stream.events.Characters;public class Example {
        public static void main(final String[] args) {
            try(FileReader reader = new FileReader("/tmp/response.xml")){
                    XMLInputFactory factory = XMLInputFactory.newFactory();
                    factory.setProperty("javax.xml.stream.isCoalescing",Boolean.TRUE);
                    XMLEventReader xereader = factory.createXMLEventReader(reader);
                    while(xereader.hasNext()){
                        XMLEvent e = xereader.nextEvent();
                        if(e.isCharacters()){
                            Characters cdata = e.asCharacters();
                            if(cdata.isWhiteSpace()) continue;
                            System.out.println(cdata.getData());
                        }
                    }
                    xereader.close();
                } catch (XMLStreamException|IOException e){
                System.err.println(e.getMessage());
            }
        }
    }
    ID
    XM
    GMS
    XB  
      
    GMS
    ID
    0011f887252346818a59fedffe6d7821
          
    XM
    李明
    XB

    GMS
    1111111111111111111
    ID
    0015224632e9476aaa8f419dcfc222b9
          
    XM
    柳眉
    XB

      

  2.   


    你好 谢谢你的回复,这种方法不是用的SAX是吧?对于30M以上的xml文件会不会出现内存溢出呢?
      

  3.   

    javax.xml.stream 和 sax 类似。可以处理 大型 XML 文档。都是基于事件处理。区别在于 一个是推一个是拉。而且 stream 还支持输出流。
      

  4.   


    恩 谢谢 我刚才试了一下 是不是这种方法必须保证标签完全是<tag></tag>这种格式的吗?我的标签里有些属性的值为空时,就会写作  <Element>GMSFZHM</Element> 
      <Value /> 
    而不是完整的<value></value>这样我运行是就会报这样的错误:
    Message: The element type "Value" must be terminated by the matching end-tag "</Value>".
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:588)
    at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(XMLEventReaderImpl.java:85)
    at sax.Example.main(Example.java:24)

      

  5.   

    没有遇到。
    我使用的是java -version
    java version "1.7.0"
    Java(TM) SE Runtime Environment (build 1.7.0-b147)
    Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)
      

  6.   

    我把这段
    <Record>
        <Element>GMS</Element>
        <Value></Value>
    </Record>
    ==>
    <Record>
        <Element>GMS</Element>
        <Value />
    </Record>
    没有问题。
      

  7.   

    我把你的代码直接拷进我的Myeclipse,有些地方会报错,我修改了一下 不知道改后是不是正确,麻烦你再帮我检查一下吧,谢谢了啊。import java.io.FileNotFoundException;
    import java.io.FileReader;import javax.xml.stream.FactoryConfigurationError;
    import javax.xml.stream.XMLEventReader;
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLStreamException;
    import javax.xml.stream.events.Characters;
    import javax.xml.stream.events.XMLEvent;public class Example {
    public static void main(final String[] args) {
             try {
    FileReader reader = new FileReader("/tmp/response.xml");
        XMLInputFactory factory = XMLInputFactory.newInstance();
        factory.setProperty("javax.xml.stream.isCoalescing",Boolean.TRUE);
        XMLEventReader xereader = factory.createXMLEventReader(reader);
        while(xereader.hasNext()){
            XMLEvent e = xereader.nextEvent();
            if(e.isCharacters()){
                Characters cdata = e.asCharacters();
                if(cdata.isWhiteSpace()) continue;
                System.out.println(cdata.getData());
            }
        }
        xereader.close();
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (FactoryConfigurationError e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (XMLStreamException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
        }
    }
      

  8.   

    没有错误。
    FileReader 那里需要修改为你自己的xml文件。循环那部分,根据你的实际需要修改,参考几个类的文档。