我可以在Java中使用一个验证性较小的StAX解析器吗?
我有以下无效的XML文件:我可以在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 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-事实上,看起来解析模式文档正是你想要的。我做了一些类似的事情