繁体   English   中英

Java Sax解析复杂的大型XML文件

[英]Java Sax to parse complex large XML file

我正在使用SAX解析一些大的XML文件,并且我想问以下问题:XML文件具有复杂的结构。 类似于以下内容:

<library>
    <books>
    <book>
        <title></title>
    <img>
        <name></name>
        <url></url>
    </img>
    ...
    ...
    </book>
    ...
    ...
</books>
<categories>
    <category id="abcd">
        <locations>
        <location>...</location>
    </locations>
    <url>...</url>
    </category>
    ...
    ... 
</categories>
<name>...</name>
<url>...</url>
</library>

事实是,这些文件每个都超过50MB,并且在不同的上下文中重复了很多标签,例如,/ books / book / img下的url,以及/ library下和/ library / categories / category下的url等。

我的SAX解析器使用DefaultHandler的子类,在其中我重写了startElement和endElement方法(以及其他方法)。 但是问题在于,由于这些XML文件的业务逻辑,这些方法在代码行方面非常庞大。 我正在用很多

if ("url".equalsIgnoreCase(qName)) {
    // peek at stack and if book is on top
    // ...
    // else if category is on top
    // ...
} else if (....) {
}

我想知道是否有更正确/正确/优雅的方法来执行xml解析。

谢谢你们

可以做的是为不同的上下文实现单独的 ContentHandler 例如,为<books>写一<books> ,为<categories>写一<books> ,为顶层一本。

然后,一旦调用books startElement方法,就立即使用XMLReader.setContentHandler()切换ContentHandler 然后将<books>特定ContentHandler切换回顶层处理程序当其到endElement方法被称为用于books

这样,每个ContentHandler可以专注于XML的特定部分,而无需了解所有其他部分。

唯一丑陋的部分是特定的处理程序需要了解顶级处理程序以及何时切换回该处理程序,可以通过提供一个简单的“处理程序堆栈”来为您解决该问题。

不知道您要问的是1)除了针对一堆字符串检查标记之外,还可以执行其他操作吗?2)是否可以使用长的if-then-else语句替代方法。

1的答案不是我找到的。 其他人可能会解决这个问题。

2的答案取决于您的域。 我看到的一种方法是,如果这样做的目的是从XML文件中合并一堆对象,则可以使用工厂方法。

因此,第一个工厂方法具有长的if if else语句,该语句仅将XML传递给适当的类。 然后,您的每个类都有一个类似ConstructYourselfFromXmlString的方法。 这将改善您的设计,因为只有对象本身才知道XML中的私人数据,以使它们水合。

很难做到这一点的原因是,如果考虑到这一点,将Object导出为XML并导入回来确实违反了封装。 没事做,就是这样。 这至少使事情变得更加封装。

高温超导

同意将对象导出为XML违反封装的观点,使用SAX来处理嵌套在不同长度的标签的实际技术并不困难。

基本上,保留一个StringBuffer,它将在文档中维护您的“位置”,该目录将是类似于您当前所在的嵌套标签的目录。 例如,如果当前字符串缓冲区的内容是/library/book/img/url那么您知道它是一本书中图像的URL,而不是某个类别的URL。

一旦确保“路径跟踪”算法正确无误,便可以使用字符串匹配将对象创建例程包装起来,从而获得更好的处理。 代替

if ("url".equalsIgnoreCase(qName)) {
   ...
}

您现在可以替代

if (location.equalsIgnoreCase("/library/book/img/url")) {
   ...
}

如果由于某种原因这对您没有吸引力,那么还有其他解决方案。 例如,您可以制作一个SAX处理程序,该处理程序实现一堆处理程序,其中顶级处理程序仅负责处理XML文档的一部分,并在处理完成后自动将其弹出堆栈。 使用这种方案,每个对象都由其自己唯一的个体处理程序创建,并且某些处理程序基本上会检查并指示在适当的时间将哪些“对象创建”处理程序推入处理堆栈。

我已经使用了两种技术。 两者都有优势,哪种才是最佳取决于您的输入和所需的对象。

您可以重构SAX内容处理,以便注册一组规则,每个规则都有一个适用于它的测试,以查看它是否与元素匹配,如果符合则执行一个操作。 这将更接近XSLT处理模型,同时仍在进行流处理。 或者,您可以转向XSLT-处理50Mb输入文件完全在现代XSLT处理器的能力范围内。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM