您将如何使用Java处理各种XML文档?

时间:2008-08-27 16:55:59

标签: java xml sax stax

我正在寻找使用Java应用程序解析各种XML文档的最佳方法。我目前正在使用SAX和自定义内容处理程序执行此操作,它运行良好 - zippy和稳定。

我决定探索具有相同程序的选项,该程序目前收到单个格式的XML文档,接收两种额外的XML文档格式,以及各种XML元素更改。我希望只根据文档中的第一个“startElement”将ContentHandler换成适当的一个......但是,呃呃,设置了ContentHandler,然后解析了文档!

... constructor ...
{
SAXParserFactory spf = SAXParserFactory.newInstance();

try {
SAXParser sp = spf.newSAXParser();
parser = sp.getXMLReader();
parser.setErrorHandler(new MyErrorHandler());
} catch (Exception e) {} 

... parse StringBuffer ...
try {
parser.setContentHandler(pP);
parser.parse(new InputSource(new StringReader(xml.toString())));
return true;
} catch (IOException e) {
    e.printStackTrace();
} catch (SAXException e) {
    e.printStackTrace();
}
...

所以,似乎我不能按照我最初的想法做到这一点。

话虽如此,我是否完全错了?使用相同的XML处理代码解析多个离散XML文档的最佳方法是什么? I tried to ask in a more general post earlier... but, I think I was being too vague。出于速度和效率的目的,我从未真正关注过DOM,因为这些XML文档非常庞大,系统每隔几分钟就会收到大约1200个文档。这只是单向发送信息

使这个问题太长,加剧了我的困惑;以下是一些各种XML文档的模型,我希望有一个单独的SAX,StAX或??解析器干净利落地处理。

products.xml:

<products>
<product>
  <id>1</id>
  <name>Foo</name>
<product>
  <id>2</id>
  <name>bar</name>
</product>
</products>

stores.xml:

<stores>
<store>
  <id>1</id>
  <name>S1A</name>
  <location>CA</location>
</store>
<store>
  <id>2</id>
  <name>A1S</name>
  <location>NY</location>
</store>
</stores>

managers.xml:

<managers>
<manager>
  <id>1</id>
  <name>Fen</name>
  <store>1</store>
</manager>
<manager>
  <id>2</id>
  <name>Diz</name>
  <store>2</store>
</manager>
</managers>

9 个答案:

答案 0 :(得分:3)

据我了解,问题是您在解析之前不知道文档的格式。您可以使用委托模式。我假设你没有验证DTD / XSD /等等,并且DefaultHandler可以有状态。

public class DelegatingHandler extends DefaultHandler {

    private Map<String, DefaultHandler> saxHandlers;
    private DefaultHandler delegate = null;

    public DelegatingHandler(Map<String, DefaultHandler> delegates) {
        saxHandlers = delegates;
    }

    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
       if(delegate == null) {
           delegate = saxHandlers.get(name);
       }
       delegate.startElement(uri, localName, name, attributes);
    }

    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        delegate.endElement(uri, localName, name);
    }

//etcetera...

答案 1 :(得分:2)

你已经很好地解释了你想做什么而不是为什么。有几个XML框架可以简化XML对象的编组和解组。

最简单的是Commons Digester,我通常用它来解析配置文件。但是,如果您想要处理Java对象,那么您应该查看CastorJiBXJAXBXMLBeansXStream或类似内容。 Castor或JiBX是我的两个最爱。

答案 2 :(得分:2)

我曾经尝试过SAXParser,但是一旦我找到了XStream,我就再也没有回过头来。使用XStream,您可以创建Java对象并将它们转换为XML。发送它们并使用XStream重新创建对象。非常易于使用,快速,并创建干净的XML。

无论哪种方式,您都必须知道从XML文件接收哪些数据。您可以通过不同方式发送它们以了解要使用的解析器。或者有一个数据对象可以容纳所有内容,但只填充一个结构(产品/商店/经理)。也许是这样的:

public class DataStructure {

    List<ProductStructure> products;

    List<StoreStructure> stors;

    List<ManagerStructure> managers;

    ...

    public int getProductCount() {
        return products.lenght();
    }

    ...
}

使用XStream转换为XML发送,然后重新创建对象。然后用它做你想做的事。

答案 3 :(得分:2)

请参阅XMLReader.setContentHandler()的文档,它说:

  

应用程序可以在解析过程中注册一个新的或不同的处理程序,SAX解析器必须立即开始使用新的处理程序。

因此,您应该能够创建一个SelectorContentHandler消费事件,直到第一个startElement事件,基于该事件更改XML阅读器上的ContentHandler,并通过第一次启动元素事件到新的内容处理程序。您只需将XMLReader传递给构造函数中的SelectorContentHandler即可。如果您需要将所有事件传递给特定于词汇表的内容处理程序,SelectorContentHandler必须缓存事件然后传递它们,但在大多数情况下,这不是必需的。

另一方面,我最近在几乎所有项目中使用XOM来处理XML ja,到目前为止,性能还不是问题。

答案 4 :(得分:1)

JAXB。 XML绑定的Java体系结构。基本上你创建了一个定义XML布局的xsd(我相信你也可以使用DTD)。然后将XSD传递给JAXB编译器,编译器创建Java类以将XML文档编组和解组为Java对象。这很简单。

顺便说一句,jaxb有命令行选项来指定要将结果类放入的包名称等。

答案 5 :(得分:0)

如果你想要更多动态处理,Stax方法可能比Sax更好。 这仍然是相当低级别的;如果你想要更简单的方法,XStream和JAXB是我的最爱。但它们确实需要非常严格的对象来映射。

答案 6 :(得分:0)

同意StaxMan,有趣的是他希望你使用Stax。它是一个基于拉取的解析器,而不是您当前使用的推送。这需要对您的代码进行一些重大更改。

答案 7 :(得分:0)

: - )

是的,我对Stax有偏见。但正如我所说,数据绑定通常比流式解决方案更方便。但如果它是你想要的流,并且不需要流水线(多个过滤阶段),Stax比SAX更简单。

还有一件事:就像XOM一样好(wrt替代品),如果你不处理“以文档为中心”的xml(〜= xhtml页面,docbook,开放式办公室文档),通常使用树模型是不正确的)。 对于数据交换,配置文件等数据绑定更方便,更高效,更自然。对于这些用例,对DOM这样的树模型说不。 所以,JAXB,XStream,JibX都很好。或者,对于更多获得的味道,消化器,蓖麻,xmlbeans。

答案 8 :(得分:0)

VTD-XML因其作为重型XML处理的最佳XML处理技术而闻名。请参阅以下参考资料以获取证明

http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf