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