Java 如何在一个文档中解析多个连续的xml文件?
我有一个大文本文件,它是一系列XML有效文档,如下所示:Java 如何在一个文档中解析多个连续的xml文件?,java,xml,xml-parsing,Java,Xml,Xml Parsing,我有一个大文本文件,它是一系列XML有效文档,如下所示: <DOC> <TEXT> ... </TEXT> ... </DOC> <DOC> <TEXT> ... </TEXT> ... </DOC> ... ... ... ... 等等。没有,分隔每个单独的xml。在Java中解析并获取每个中下的值的最佳方法是什么 如果我将整个过程传递给DocumentBui
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
...
...
...
...
等等。没有
,
分隔每个单独的xml。在Java中解析并获取每个
中
下的值的最佳方法是什么
如果我将整个过程传递给DocumentBuilder,我会收到一个错误,说明文档格式不正确。有没有比简单地遍历一个字符串更好的解决方案,为每个
构建一个字符串?由于没有“根”节点,文档的格式不正确:
<ROOT>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
</ROOT>
...
...
...
...
文档格式不正确,因为您没有“根”节点:
<ROOT>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
<DOC>
<TEXT> ... </TEXT>
...
</DOC>
</ROOT>
...
...
...
...
您将很难使用“标准”XML解析器(如Xerces)对此进行解析。正如您所提到的,此XML文档的格式不好,部分原因是它缺少XML声明
,但最重要的原因是它有两个文档根(即
元素)
我建议你试试。它的目的是解析(引用)“糟糕、恶劣和野蛮”的XML。不保证,但这可能是您的最佳选择。您将很难使用“标准”XML解析器(如Xerces)对此进行解析。正如您所提到的,此XML文档的格式不好,部分原因是它缺少XML声明
,但最重要的原因是它有两个文档根(即
元素)
我建议你试试。它的目的是解析(引用)“糟糕、恶劣和野蛮”的XML。不保证,但这可能是您的最佳选择。有效的XML文档必须有一个根元素,您可以在该根元素下指定所有其他元素。此外,文档中只能存在一个根元素。看看 因此,为了解决您的问题,您可以将文本文件的所有内容放入一个字符串(或StringBuffer/StringBuilder…)中,并将该字符串置于
和
标记之间
e、 g,
String origXML=readContentFromTextFile(文件名);
字符串validXML=“”+origXML+”;
//解析validXML
有效的XML文档必须有一个根元素,您可以在该根元素下指定所有其他元素。此外,文档中只能存在一个根元素。看看
因此,为了解决您的问题,您可以将文本文件的所有内容放入一个字符串(或StringBuffer/StringBuilder…)中,并将该字符串置于
和
标记之间
e、 g,
String origXML=readContentFromTextFile(文件名);
字符串validXML=“”+origXML+”;
//解析validXML
您可以尝试使用xslt进行解析。您可以尝试使用xslt进行解析。您可以创建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;
}
}
public类封闭的InputStream扩展了InputStream{
私有枚举状态{
前缀、流、后缀、EOF
};
私有最终字节[]前缀;
私有最终输入流;
私有最终字节[]后缀;
私有状态State=State.PREFIX;
私有整数索引;
封闭的输入流(字节[]前缀,输入流,字节[]后缀){
this.prefix=前缀;
this.stream=流;
this.suffix=后缀;
}
@凌驾
public int read()引发IOException{
if(state==state.PREFIX){
如果(索引<前缀长度){
返回前缀[index++]&0xFF;
}
state=state.STREAM;
}
if(state==state.STREAM){
int r=stream.read();
如果(r>=0){
返回r;
}
state=state.SUFFIX;
指数=0;
}
if(state==state.SUFFIX){
如果(索引<后缀长度){
返回后缀[index++]&0xFF;
}
state=state.EOF;
}
返回-1;
}
}
您可以创建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;
}
}
public类封闭的InputStream扩展了InputStream{
私有枚举状态{
前缀、流、后缀、EOF
};
私有最终字节[]前缀;
私有最终输入流;
私有最终字节[]后缀;
私有状态State=State.PREFIX;
私有整数索引;
封闭的输入流(字节[]前缀,输入流,字节[]后缀){
this.prefix=前缀;
this.stream=流;
this.suffix=后缀;
}
@凌驾
public int read()引发IOException{
if(state==state.PREFIX){
如果(索引<前缀长度){
返回前缀[index++]&0xFF;
}
state=state.STREAM;
}
if(state==state.STREAM){
int r=stream.read();
如果(r>=0){
返回r;
}
state=state.SUFFIX;
指数=0;
}
if(state==state.SUFFIX){
如果(索引<后缀长度){
返回后缀[index++]&0xFF;
}
state=state.EOF;
}
返回-1;
}
}
为什么需要InputStream作为构造函数中的参数?您可以使用super.read()而不是stream.read()(因为EnclosedInputStream是InputStream的子类)。您不必访问使用原始内容创建InputStream的代码。例如,假设您有一个URL,为什么需要InputStream作为构造函数中的参数?您可以使用super.read()而不是stream.read()(因为EnclosedInputStream是InputStream的一个子类)