我可以在Java中使用一个验证性较小的StAX解析器吗?

我可以在Java中使用一个验证性较小的StAX解析器吗?,java,xml,streaming,xml-parsing,stax,Java,Xml,Streaming,Xml Parsing,Stax,我有以下无效的XML文件: <?xml version="1.0" encoding="utf-8" ?> <Page num="1" crop_box="0, 0, 595, 842" media_box="0, 0, 595, 842" rotate="0"> <Flow id="1"> <Para id="1"> <Line box="90, 754.639, 120.038, 12"&g

我有以下无效的XML文件:

<?xml version="1.0" encoding="utf-8" ?>
<Page num="1" crop_box="0, 0, 595, 842" media_box="0, 0, 595, 842" rotate="0">
    <Flow id="1">
        <Para id="1">
            <Line box="90, 754.639, 120.038, 12">
                <Word box="90, 754.639, 22.6704, 12">This</Word>
            </Line>
        </Para>
    </Flow>
</Page>
<?xml version="1.0" encoding="utf-8" ?>
<Page num="1" crop_box="0, 0, 595, 842" media_box="0, 0, 595, 842" rotate="0">
    <Flow id="1">
        <Para id="1">
            <Line box="90, 754.639, 120.038, 12">
                <Word box="90, 754.639, 22.6704, 12">This</Word>
            </Line>
        </Para>
    </Flow>
</Page>

这
这
虽然它在结构上是无效的(它有两个根元素,XML序言显示两次),但仍然可以正确解析它(即标记正确,内容也正确)


所以,问题是,Java中是否有一个StAX(或任何其他基于流的)XML解析器允许我这样做?我已经检查了XMLInputFactory中的所有选项,但它们似乎都不允许解析器接受这种格式错误的XML。

我严重怀疑您是否能够获得任何标准java工具来按原样解析文档。但是,您可以自己找到边界并解析各个文档。只需查找出现的
“我严重怀疑您是否能够获得任何标准java工具来按原样解析文档。但是,您可以自己找到边界并解析单个文档。只需查找出现的
”只需编写一个
FilterReader
FilterInputStream
派生类,当它看到一个新的XML头时返回一次EOF。

只需编写一个
FilterReader
FilterInputStream
派生类,当它看到一个新的XML头时返回一次EOF。

我制作了一个解析方法,可以return me message是message类型的类(它是my类,包含我需要过滤掉的Rss内容)

我的方法如下

    @Override
public List<Message> parse() {
    // TODO Auto-generated method stub
    final Message currentMessage = new Message();
    RootElement root = new RootElement(RSS);
    final List<Message> message = new ArrayList<Message>();
    Element channel = root.getChild(CHANNEL);
    Element item = channel.getChild(ITEM);

    item.setEndElementListener(new EndElementListener() {

        @Override
        public void end() {
            message.add(currentMessage.copy());     
        }
    });

    item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setTitle(body);
        }
    }); 

    item.getChild(LINK).setEndTextElementListener(new EndTextElementListener() {
        @Override
        public void end(String body) {
            currentMessage.setLink(body);   
        }
    });
    item.getChild(DESCRIPTION).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setDescription(body);
        }
    });
    item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setDate(body);
        }
    });
    /*item.getChild(IMAGE).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setImage(body);
        }
    });*/

    try {
        Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch(Exception e){
        e.printStackTrace();
    }


    return message;
}
@覆盖
公共列表解析(){
//TODO自动生成的方法存根
最终消息currentMessage=新消息();
RootElement root=新的RootElement(RSS);
最终列表消息=新建ArrayList();
元素通道=root.getChild(通道);
元素项=channel.getChild(项);
item.setEndElementListener(新的EndElementListener(){
@凌驾
公共无效结束(){
message.add(currentMessage.copy());
}
});
item.getChild(TITLE.setEndTextElementListener(新的EndTextElementListener()){
公共无效结束(字符串体){
currentMessage.setTitle(正文);
}
}); 
item.getChild(LINK.setEndTextElementListener(新的EndTextElementListener()){
@凌驾
公共无效结束(字符串体){
currentMessage.setLink(正文);
}
});
item.getChild(DESCRIPTION).setEndTextElementListener(新的EndTextElementListener(){
公共无效结束(字符串体){
currentMessage.setDescription(正文);
}
});
item.getChild(发布日期).setEndTextElementListener(新的EndTextElementListener(){
公共无效结束(字符串体){
currentMessage.setDate(正文);
}
});
/*item.getChild(IMAGE.setEndTextElementListener(新的EndTextElementListener()){
公共无效结束(字符串体){
currentMessage.setImage(主体);
}
});*/
试一试{
parse(this.getInputStream(),Xml.Encoding.UTF_8,root.getContentHandler());
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(SAXE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
捕获(例外e){
e、 printStackTrace();
}
返回消息;
}

希望这对我有所帮助

我制作了一个解析方法,返回我的消息,它是message类型的类(它是我的类,有我需要过滤掉的Rss内容的部分)

我的方法如下

    @Override
public List<Message> parse() {
    // TODO Auto-generated method stub
    final Message currentMessage = new Message();
    RootElement root = new RootElement(RSS);
    final List<Message> message = new ArrayList<Message>();
    Element channel = root.getChild(CHANNEL);
    Element item = channel.getChild(ITEM);

    item.setEndElementListener(new EndElementListener() {

        @Override
        public void end() {
            message.add(currentMessage.copy());     
        }
    });

    item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setTitle(body);
        }
    }); 

    item.getChild(LINK).setEndTextElementListener(new EndTextElementListener() {
        @Override
        public void end(String body) {
            currentMessage.setLink(body);   
        }
    });
    item.getChild(DESCRIPTION).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setDescription(body);
        }
    });
    item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setDate(body);
        }
    });
    /*item.getChild(IMAGE).setEndTextElementListener(new EndTextElementListener(){
        public void end(String body) {
            currentMessage.setImage(body);
        }
    });*/

    try {
        Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch(Exception e){
        e.printStackTrace();
    }


    return message;
}
@覆盖
公共列表解析(){
//TODO自动生成的方法存根
最终消息currentMessage=新消息();
RootElement root=新的RootElement(RSS);
最终列表消息=新建ArrayList();
元素通道=root.getChild(通道);
元素项=channel.getChild(项);
item.setEndElementListener(新的EndElementListener(){
@凌驾
公共无效结束(){
message.add(currentMessage.copy());
}
});
item.getChild(TITLE.setEndTextElementListener(新的EndTextElementListener()){
公共无效结束(字符串体){
currentMessage.setTitle(正文);
}
}); 
item.getChild(LINK.setEndTextElementListener(新的EndTextElementListener()){
@凌驾
公共无效结束(字符串体){
currentMessage.setLink(正文);
}
});
item.getChild(DESCRIPTION).setEndTextElementListener(新的EndTextElementListener(){
公共无效结束(字符串体){
currentMessage.setDescription(正文);
}
});
item.getChild(发布日期).setEndTextElementListener(新的EndTextElementListener(){
公共无效结束(字符串体){
currentMessage.setDate(正文);
}
});
/*item.getChild(IMAGE.setEndTextElementListener(新的EndTextElementListener()){
公共无效结束(字符串体){
currentMessage.setImage(主体);
}
});*/
试一试{
parse(this.getInputStream(),Xml.Encoding.UTF_8,root.getContentHandler());
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(SAXE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
捕获(例外e){
e、 printStackTrace();
}
返回消息;
}

希望这有帮助

我做了一些类似的事情(),但主要的问题是我对性能不满意,如果我可以直接接收令牌,而不关心文件的验证,那会简单得多。而且似乎有一个验证性较差的解析器,Woodstox在解析\u MODE\u FRAGMENT()。我要试试。@MaurícioLinhares-事实上,看起来解析模式文档正是你想要的。我做了一些类似的事情