我有一个大文本文件,它是一系列XML有效文档,如下所示:
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
等。没有<?xml version="1.0">
,<DOC></DOC>
分隔每个单独的xml。在Java中解析此问题的最佳方法是什么,并在每个<TEXT>
中获取<DOC>
下的值?
如果我将整个内容传递给DocumentBuilder,我会收到一条错误消息,指出文档格式不正确。有没有比简单遍历更好的解决方案,为每个<DOC>
建立一个字符串?
答案 0 :(得分:5)
有效 XML文档必须具有 root 元素,您可以在其下指定所有其他元素。此外,在文档中只能存在一个 root 元素。看看XML Specification (see point 2)
因此,为了克服您的问题,您可以将文本文件的所有内容转换为String(或StringBuffer / StringBuilder ...)并将此字符串放在<root>
和</root>
标记之间
例如,
String origXML = readContentFromTextFile(fileName);
String validXML = "<root>" + origXML + "</root>";
//parse validXML
答案 1 :(得分:2)
由于您没有“根”节点,因此文档格式不正确:
<ROOT>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
</ROOT>
答案 2 :(得分:1)
使用“标准”XML解析器(如Xerces)解析此问题很困难。正如您所提到的,XML文档的格式不正确,部分原因是它缺少XML声明<?xml version="1.0"?>
,但最重要的是因为它有两个文档根(即<doc>
元素)。
我建议你试试TagSoup。它打算解析(引用)“糟糕,讨厌和野蛮”的XML。不保证,但这可能是你最好的镜头。
答案 3 :(得分:0)
您可以尝试使用xslt进行解析。
答案 4 :(得分:0)
您可以创建InputStream的子类,为输入流添加前缀和后缀,并将该类的实例传递给任何XML解析器:
public class EnclosedInputStream extends InputStream {
private enum State {
PREFIX, STREAM, SUFFIX, EOF
};
private final byte[] prefix;
private final InputStream stream;
private final byte[] suffix;
private State state = State.PREFIX;
private int index;
EnclosedInputStream(byte [] prefix, InputStream stream, byte[] suffix) {
this.prefix = prefix;
this.stream = stream;
this.suffix = suffix;
}
@Override
public int read() throws IOException {
if (state == State.PREFIX) {
if (index < prefix.length) {
return prefix[index++] & 0xFF;
}
state = State.STREAM;
}
if (state == State.STREAM) {
int r = stream.read();
if (r >= 0) {
return r;
}
state = State.SUFFIX;
index = 0;
}
if (state == State.SUFFIX) {
if (index < suffix.length) {
return suffix[index++] & 0xFF;
}
state = State.EOF;
}
return -1;
}
}