2011-05-10 138 views
1

我有一個很大的文本文件,XML的有效證件的序列看起來是這樣的:如何在一個文檔中解析多個連續的xml文件?

<DOC> 
    <TEXT> ... </TEXT> 
    ... 
</DOC> 
<DOC> 
    <TEXT> ... </TEXT> 
    ... 
</DOC> 

等沒有<?xml version="1.0">,該<DOC></DOC>界定每個單獨的XML。在Java中解析這個問題的最佳方式是什麼?在<DOC>中獲取<TEXT>下的值?

如果我將整個事情傳遞給一個DocumentBuilder,我會收到一個錯誤,指出文檔格式不正確。有沒有比簡單遍歷更好的解決方案,建立一個字符串爲每個<DOC>

回答

5

A 有效 XML文檔必須有一個根元素元素,您可以在其中指定所有其他元素。另外,在文件中只能有一個元素可以存在。對XML Specification (see point 2)

一看這樣,克服您的問題,你可以把你的文本文件的所有內容爲一個字符串(或StringBuffer的/ StringBuilder的...),並把這個字符串<root></root>標籤之間 如,

String origXML = readContentFromTextFile(fileName); 
String validXML = "<root>" + origXML + "</root>"; 
//parse validXML 
2

文檔的格式不正確,因爲你沒有「根」節點:

<ROOT> 
    <DOC> 
     <TEXT> ... </TEXT> 
     ... 
    </DOC> 
    <DOC> 
     <TEXT> ... </TEXT> 
     ... 
    </DOC> 
</ROOT> 
1

你也很難用「標準」的XML解析器,例如Xerces的解析這一點。正如你所提到的,這個XML文檔不完整,部分原因是它缺少一個XML聲明<?xml version="1.0"?>,但最重要的是因爲它有兩個文檔根(即<doc>元素)。我建議你試試TagSoup。它是爲了解析(引用)「糟糕,討厭和粗暴」的XML。沒有保證,但這可能是你最好的選擇。

+0

謝謝你的提示。該鏈接中的網站不再存在。 'TagSoup'變成了其他的鏈接,但很難說出什麼是經典。 – smci 2017-10-13 18:11:32

0

您可以嘗試使用xslt進行分析。

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; 
    } 
} 
+0

爲什麼你需要InputStream作爲構造函數中的參數?你可以使用super.read()而不是stream.read()(因爲EnclosedInputStream是InputStream的子類)。 – 2011-05-10 10:46:45

+0

您不一定有權訪問使用原始內容創建InputStream的代碼。假設你有一個URL的例子。 – 2011-05-10 10:57:39