在 Java 中使用 SAX 解析大型 XML
Posted
技术标签:
【中文标题】在 Java 中使用 SAX 解析大型 XML【英文标题】:parsing large XML using SAX in java 【发布时间】:2011-08-06 14:48:38 【问题描述】:我正在尝试解析堆栈溢出数据转储,其中一张表名为 posts.xml,其中包含大约 1000 万个条目。示例 xml:
<?xml version="1.0" encoding="utf-8"?>
<posts>
<row Id="1" PostTypeId="1" AcceptedAnswerId="26" CreationDate="2010-07-07T19:06:25.043" Score="10" ViewCount="1192" Body="<p>Now that the Engineer update has come, there will be lots of Engineers building up everywhere. How should this best be handled?</p>
" OwnerUserId="11" LastEditorUserId="56" LastEditorDisplayName="" LastEditDate="2010-08-27T22:38:43.840" LastActivityDate="2010-08-27T22:38:43.840" Title="In Team Fortress 2, what is a good strategy to deal with lots of engineers turtling on the other team?" Tags="<strategy><team-fortress-2><tactics>" AnswerCount="5" CommentCount="7" />
<row Id="2" PostTypeId="1" AcceptedAnswerId="184" CreationDate="2010-07-07T19:07:58.427" Score="5" ViewCount="469" Body="<p>I know I can create a Warp Gate and teleport to Pylons, but I have no idea how to make Warp Prisms or know if there's any other unit capable of transporting.</p>

<p>I would in particular like this to built remote bases in 1v1</p>
" OwnerUserId="10" LastEditorUserId="68" LastEditorDisplayName="" LastEditDate="2010-07-08T00:16:46.013" LastActivityDate="2010-07-08T00:21:13.163" Title="What protoss unit can transport others?" Tags="<starcraft-2><how-to><protoss>" AnswerCount="3" CommentCount="2" />
<row Id="3" PostTypeId="1" AcceptedAnswerId="56" CreationDate="2010-07-07T19:09:46.317" Score="7" ViewCount="356" Body="<p>Steam won't let me have two instances running with the same user logged in.</p>

<p>Does that mean I cannot run a dedicated server on a PC (for example, for Left 4 Dead 2) <em>and</em> play from another machine?</p>

<p>Is there a way to run the dedicated server without running steam? Is there a configuration option I'm missing?</p>
" OwnerUserId="14" LastActivityDate="2010-07-07T19:27:04.777" Title="How can I run a dedicated server from steam?" Tags="<steam><left-4-dead-2><dedicated-server><account>" AnswerCount="1" />
<row Id="4" PostTypeId="1" AcceptedAnswerId="14" CreationDate="2010-07-07T19:11:05.640" Score="10" ViewCount="201" Body="<p>When I get to the insult sword-fighting stage of The Secret of Monkey Island, do I have to learn every single insult and comeback in order to beat the Sword Master?</p>
" OwnerUserId="17" LastEditorUserId="17" LastEditorDisplayName="" LastEditDate="2010-07-08T21:25:04.787" LastActivityDate="2010-07-08T21:25:04.787" Title="Do I have to learn all of the insults and comebacks to be able to advance in The Secret of Monkey Island?" Tags="<monkey-island><adventure>" AnswerCount="3" CommentCount="2" />
我想解析这个xml,但只加载xml的某些属性,即Id、PostTypeId、AcceptedAnswerId和其他2个属性。 SAX 中有没有办法让它只加载这些属性?如果有那怎么办?我对 SAX 很陌生,所以一些指导会有所帮助。
否则加载整个东西会很慢,而且某些属性无论如何都不会被使用,所以没用。
另一个问题是,是否可以跳转到具有行 ID X 的特定行?如果可能的话,我该怎么做?
【问题讨论】:
这是来自 data.stackexchange.com 的数据? SAX 仍然必须解析输入,无论您是否使用它。而且由于从输入中提取字符串(实际上是对这些字符串进行垃圾收集)会付出很大的代价,因此尝试过滤它实际提供给您的属性没有多大意义。 您确定要使用 SAX 吗?如果您只需要使用比 DOM 更轻量级的东西,也许可以看看 Stax (javax.xml.stream),它与 SAX 一样快,但通常使用起来更简单,因为您迭代内容而不是编写事件处理程序.至于跳到特定的行;不,默认情况下都不允许这样做。通常使用 XPath 以这种方式定位事物,但这需要完整的内存树 (DOM/XOM/JDOM) 【参考方案1】:“StartElement”Sax 事件允许处理单个 XML 元素。
在java代码中你必须实现这个方法
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException
if("row".equals(localName))
//this code is executed for every xml element "row"
String id = attributes.getValue("id");
String PostTypeId = attributes.getValue("PostTypeId");
String AcceptedAnswerId = attributes.getValue("AcceptedAnswerId");
//others two
// you have your att values for an "row" element
对于每个元素,您可以访问:
-
命名空间 URI
XML QName
XML 本地名称
属性映射,在这里你可以提取你的两个属性...
具体细节见 ContentHandler 实现。
再见
更新:改进了以前的 sn-p。
【讨论】:
你能在开始和结束时为我的案例放一个代码 sn-p 示例吗?因为我的 xml 看起来不像你的例子 我上面例子中的 URI 和 LocalName 是什么 这种情况下你没有uri,localname是"row"【参考方案2】:这与我已经回答 here 的方法几乎相同。
向下滚动到org.xml.sax Implementation
部分。您只需要一个自定义处理程序。
【讨论】:
【参考方案3】:是的,你可以重写只处理你想要的元素的方法:
http://www.javacommerce.com/displaypage.jsp?name=saxparser1.sql&id=18232 http://www.java2s.com/Code/Java/XML/SAXDemo.htm【讨论】:
【参考方案4】:SAX 不“加载”元素。它会通知您的应用程序每个元素的开始和结束,并且完全由您的应用程序决定它需要注意哪些元素。
【讨论】:
以上是关于在 Java 中使用 SAX 解析大型 XML的主要内容,如果未能解决你的问题,请参考以下文章