Java 这里使用哪种XML解析器?

Java 这里使用哪种XML解析器?,java,xml,jaxb,xml-parsing,Java,Xml,Jaxb,Xml Parsing,我接收到一个XML文件作为输入,其大小可以从几KBs到更多。我正在通过网络获取此文件。我需要根据我的使用情况提取少量节点,所以大部分文档对我来说都是无用的。我没有记忆偏好,我只需要速度 考虑到所有这些,我得出结论: 这里不使用DOM(因为可能有巨大的文档大小,没有CRUD要求,并且源是网络) 没有SAX,因为我只需要获取一小部分数据 斯塔克斯可能是一条路要走,但我不确定它是否是最快的路 JAXB是另一种选择——但它使用什么样的解析器呢?我读到它默认使用Xerces(这是什么类型-推还是拉?),尽

我接收到一个XML文件作为输入,其大小可以从几KBs到更多。我正在通过网络获取此文件。我需要根据我的使用情况提取少量节点,所以大部分文档对我来说都是无用的。我没有记忆偏好,我只需要速度

考虑到所有这些,我得出结论:

  • 这里不使用DOM(因为可能有巨大的文档大小,没有CRUD要求,并且源是网络)

  • 没有SAX,因为我只需要获取一小部分数据

  • 斯塔克斯可能是一条路要走,但我不确定它是否是最快的路

  • JAXB是另一种选择——但它使用什么样的解析器呢?我读到它默认使用Xerces(这是什么类型-推还是拉?),尽管我可以根据下面的说明将它配置为与Stax或Woodstock一起使用

  • 我读了很多书,仍然对这么多的选择感到困惑!任何帮助都将不胜感激

    谢谢


    编辑:我想在这里再添加一个问题:在这里使用JAXB有什么错?

    我认为您应该使用SAX或基于SAX的解析器。我推荐你使用apache Digester。
    SAX是事件驱动的,不存储状态。这就是您在这里需要的,因为您只需要提取文档的一小部分(我猜是一个标记)。

    到目前为止,最快的解决方案是一个StAX解析器,特别是当您只需要XML文件的一个特定子集,并且您可以很容易地忽略使用StAX不需要的任何内容,而如果使用SAX解析器,则无论如何都会收到事件

    但它也比使用SAX或DOM稍微复杂一点。有一天,我不得不为以下XML编写一个StAX解析器:

    <?xml version="1.0"?>
    <table>
        <row>
            <column>1</column>
            <column>Nome</column>
            <column>Sobrenome</column>
            <column>email@gmail.com</column>
            <column></column>
            <column>2011-06-22 03:02:14.915</column>
            <column>2011-06-22 03:02:25.953</column>
            <column></column>
            <column></column>
        </row>
    </table>    
    
    
    1.
    诺姆
    Sobrenome
    email@gmail.com
    2011-06-22 03:02:14.915
    2011-06-22 03:02:25.953
    
    下面是最终解析器代码的样子:

    public class Parser {
    
    private String[] files ;
    
    public Parser(String ... files) {
        this.files = files;
    }
    
    private List<Inscrito> process() {
    
        List<Inscrito> inscritos = new ArrayList<Inscrito>();
    
    
        for ( String file : files ) {
    
            XMLInputFactory factory = XMLInputFactory.newFactory();
    
            try {
    
                String content = StringEscapeUtils.unescapeXml( FileUtils.readFileToString( new File(file) ) );
    
                XMLStreamReader parser = factory.createXMLStreamReader( new ByteArrayInputStream( content.getBytes() ) );
    
                String currentTag = null;
                int columnCount = 0;
                Inscrito inscrito = null;           
    
                while ( parser.hasNext() ) {
    
                    int currentEvent = parser.next();
    
                    switch ( currentEvent ) {
                    case XMLStreamReader.START_ELEMENT: 
    
                        currentTag = parser.getLocalName();
    
                        if ( "row".equals( currentTag ) ) {
                            columnCount = 0;
                            inscrito = new Inscrito();                      
                        }
    
                        break;
                    case XMLStreamReader.END_ELEMENT:
    
                        currentTag = parser.getLocalName();
    
                        if ( "row".equals( currentTag ) ) {
                            inscritos.add( inscrito );
                        }
    
                        if ( "column".equals( currentTag ) ) {
                            columnCount++;
                        }                   
    
                        break;
                    case XMLStreamReader.CHARACTERS:
    
                        if ( "column".equals( currentTag ) ) {
    
                            String text = parser.getText().trim().replaceAll( "\n" , " "); 
    
                            switch( columnCount ) {
                            case 0:
                                inscrito.setId( Integer.valueOf( text ) );
                                break;
                            case 1:                         
                                inscrito.setFirstName( WordUtils.capitalizeFully( text ) );
                                break;
                            case 2:
                                inscrito.setLastName( WordUtils.capitalizeFully( text ) );
                                break;
                            case 3:
                                inscrito.setEmail( text );
                                break;
                            }
    
                        }
    
                        break;
                    }
    
                }
    
                parser.close();
    
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }           
    
        }
    
        Collections.sort(inscritos);
    
        return inscritos;
    
    }
    
    public Map<String,List<Inscrito>> parse() {
    
        List<Inscrito> inscritos = this.process();
    
        Map<String,List<Inscrito>> resultado = new LinkedHashMap<String, List<Inscrito>>();
    
        for ( Inscrito i : inscritos ) {
    
            List<Inscrito> lista = resultado.get( i.getInicial() );
    
            if ( lista == null ) {
                lista = new ArrayList<Inscrito>();
                resultado.put( i.getInicial(), lista );
            }
    
            lista.add( i );
    
        }
    
        return resultado;
    }
    
    }
    
    公共类解析器{
    私有字符串[]文件;
    公共解析器(字符串…文件){
    this.files=文件;
    }
    私有列表进程(){
    List inscritos=new ArrayList();
    用于(字符串文件:文件){
    XMLInputFactory=XMLInputFactory.newFactory();
    试一试{
    String content=StringEscapeUtils.unescapeXml(FileUtils.readFileToString(新文件(File));
    XMLStreamReader parser=factory.createXMLStreamReader(新的ByteArrayInputStream(content.getBytes());
    字符串currentTag=null;
    int columnCount=0;
    Inscrito Inscrito=null;
    while(parser.hasNext()){
    int currentEvent=parser.next();
    开关(当前事件){
    案例XMLStreamReader.START_元素:
    currentTag=parser.getLocalName();
    如果(“行”。等于(当前标记)){
    columnCount=0;
    inscrito=新的inscrito();
    }
    打破
    案例XMLStreamReader.END_元素:
    currentTag=parser.getLocalName();
    如果(“行”。等于(当前标记)){
    inscritos.add(inscrito);
    }
    如果(“列“.equals(currentTag)){
    columnCount++;
    }                   
    打破
    大小写XMLStreamReader.CHARACTERS:
    如果(“列“.equals(currentTag)){
    String text=parser.getText().trim().replaceAll(“\n”,”);
    开关(列计数){
    案例0:
    inscrito.setId(Integer.valueOf(text));
    打破
    案例1:
    inscrito.setFirstName(WordUtils.capitalizely(text));
    打破
    案例2:
    inscrito.setLastName(WordUtils.capitalizely(text));
    打破
    案例3:
    inscrito.setEmail(文本);
    打破
    }
    }
    打破
    }
    }
    parser.close();
    }捕获(例外e){
    抛出新的非法状态异常(e);
    }           
    }
    集合。排序(inscritos);
    返回标准;
    }
    公共映射解析(){
    List inscritos=this.process();
    Map resultado=新建LinkedHashMap();
    对于(Inscrito i:inscritos){
    List lista=resultado.get(i.getinical());
    if(lista==null){
    lista=新的ArrayList();
    resultado.put(i.getinical(),lista);
    }
    添加(i);
    }
    返回resultado;
    }
    }
    

    代码本身是葡萄牙语的,但您应该能够直接理解它是什么。

    如果您只提取少量,考虑一下使用XPath,因为这比试图提取整个文档要简单得多。

    < P>要么SAX或StAX可以用一些复杂的工作来处理这一点,以确定你在你想要的东西上,但是为了通过显式路径提取一小部分事物,你最好是用.<
    另一种可能的策略是,首先过滤到您想要使用的部分,然后用您喜欢的任何东西进行解析,因为过滤的结果将是一个更小的文档。

    注意:我是负责人,也是JAXB 2()专家组的成员

    StAX(通常是解析XML的最快方法,Woodstox以其快速的StAX解析器而闻名。除了解析之外,您还需要收集XML数据。这就是StAX和JAXB结合使用的方便之处

    为了确保我们的JAXB实现使用Woodstox StAX i