【问题标题】:Java XML Parsing and original byte offsetsJava XML 解析和原始字节偏移
【发布时间】:2010-08-17 22:05:10
【问题描述】:
我想将一些格式良好的 XML 解析成 DOM,但我想知道每个节点的标签在原始媒体中的偏移量。
例如,如果我有一个 XML 文档,其内容类似于:
<html>
<body>
<div>text</div>
</body>
</html>
我想知道该节点在原始媒体中的偏移量 13 处开始,并且(更重要的是)“文本”从偏移量 18 处开始。
标准的 Java XML 解析器可以做到这一点吗? JAXB?如果没有容易获得的解决方案,那么解析路径上需要进行哪些类型的更改才能使其成为可能?
【问题讨论】:
标签:
java
xml
parsing
jaxb
sax
【解决方案1】:
SAX API 为此提供了一种相当模糊的机制——org.xml.sax.Locator 接口。当您使用 SAX API 时,您将子类化 DefaultHandler 并将其传递给 SAX 解析方法,并且 SAX 解析器实现应该通过 setDocumentLocator() 将 Locator 注入您的 DefaultHandler。随着解析的进行,你的ContentHandler上的各种回调方法被调用(例如startElement()),此时你可以参考Locator找出解析位置(通过getColumnNumber()和getLineNumber())
从技术上讲,这是可选功能,但 javadoc 表示“强烈鼓励”实现提供它,因此您可以假设 JavaSE 中内置的 SAX 解析器可以做到这一点。
当然,这确实意味着使用 SAX API,这不是一个有趣的想法,但我看不到使用更高级别的 API 访问这些信息的方法。
编辑:找到this example。
【解决方案2】:
使用 XML Streamreader 及其 getLocation() 方法返回位置对象。 location.getCharacterOffset() 给出当前位置的字节偏移量。
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
public class Runner {
public static void main(String argv[]) {
XMLInputFactory factory = XMLInputFactory.newInstance();
try{
XMLStreamReader streamReader = factory.createXMLStreamReader(
new FileReader("D:\\BigFile.xml"));
while(streamReader.hasNext()){
streamReader.next();
if(streamReader.getEventType() == XMLStreamReader.START_ELEMENT){
Location location = streamReader.getLocation();
System.out.println("byte location: " + location.getCharacterOffset());
}
}
} catch(Exception e){
e.printStackTrace();
}