2011-10-02 41 views
0

我有了HTML標籤包含的XML文檔:如何獲取在Java中包含其他嵌入式XML標記的<tagname>的內容?

<chapter> 
     <h1>title of content</h1> 
     <p> my paragraph ... </p> 
</chapter> 

我需要得到<chapter>標籤的內容和我的輸出將是:

 <h1>title of content</h1> 
     <p> my paragraph ... </p> 

我的問題是類似這樣的帖子: How parse XML to get one tag and save another tag inside

但我需要在Java中使用SAX或DOM實現它或...?

我在這篇文章中發現了一個使用SAX的解決方案:SAX Parser : Retrieving HTML tags from XML但它很麻煩並且不適用於大量的XML數據。

更新時間:

我的SAX實現: 在某些情況下它拋出異常:java.lang.StringIndexOutOfBoundsException:字符串索引超出範圍:-4029

public class MyXMLHandler extends DefaultHandler { 

private boolean tagFlag = false; 

private char[] temp; 
String insideTag; 
private int startPosition; 
private int endPosition; 
private String tag; 

public void startElement(String uri, String localName, String qName, 
     Attributes attributes) throws SAXException { 


    if (qName.equalsIgnoreCase(tag)) { 
     tagFlag = true; 
    } 

} 

public void endElement(String uri, String localName, String qName) 
     throws SAXException { 

    if (qName.equalsIgnoreCase(tag)) { 

     insideTag = new String(temp, startPosition, endPosition - startPosition); 
     tagFlag = false; 
    } 

} 

public void characters(char ch[], int start, int length) 
     throws SAXException { 
    temp = ch; 
    if (tagFlag) { 
     startPosition = start; 
     tagFlag = false; 
    } 
    endPosition = start + length; 
} 

public String getInsideTag(String tag) { 
    this.tag = tag; 
    return insideTag; 
} 

} 

更新2:(使用StringBuilder的)

我已經通過的StringBuilder這樣累積的字符:

public class MyXMLHandler extends DefaultHandler { 

private boolean tagFlag = false; 

private char[] temp; 
String insideTag; 
private String tag; 
private StringBuilder builder; 

public void startElement(String uri, String localName, String qName, 
     Attributes attributes) throws SAXException { 

    if (qName.equalsIgnoreCase(tag)) { 
     builder = new StringBuilder(); 
     tagFlag = true; 
    } 

} 

public void endElement(String uri, String localName, String qName) 
     throws SAXException { 

    if (qName.equalsIgnoreCase(tag)) { 
     insideTag = builder.toString(); 
     tagFlag = false; 
    } 
} 

public void characters(char ch[], int start, int length) 
     throws SAXException { 
    if (tagFlag) { 
     builder.append(ch, start, length); 
    } 
} 

public String getInsideTag(String tag) { 
    this.tag = tag; 
    return insideTag; 
} 

} 

builder.append(ch, start, length);不會在緩衝區中追加開始標記,如<EmbeddedTag atr="..."></EmbeddedTag>。此代碼打印輸出:

 title of content 
     my paragraph ... 

代替預期輸出:

 <h1>title of content</h1> 
     <p> my paragraph ... </p> 

更新3:

最後,我已經實現瞭解析器處理程序:

public class MyXMLHandler extends DefaultHandler { 

private boolean tagFlag = false; 
private String insideTag; 
private String tag; 
private StringBuilder builder; 

public void startElement(String uri, String localName, String qName, 
     Attributes attributes) throws SAXException { 

    if (qName.equalsIgnoreCase(tag)) { 
     builder = new StringBuilder(); 
     tagFlag = true; 
    } 

    if (tagFlag) { 
     builder.append("<" + qName); 
     for (int i = 0; i < attributes.getLength(); i++) { 
     builder.append(" " + attributes.getLocalName(i) + "=\"" + 
     attributes.getValue(i) + "\""); 
     } 
     builder.append(">"); 
    } 
} 

public void endElement(String uri, String localName, String qName) 
     throws SAXException { 

    if (tagFlag) { 
     builder.append("</" + qName + ">"); 
    } 

    if (qName.equalsIgnoreCase(tag)) { 
     insideTag = builder.toString();      
     tagFlag = false; 
    } 
    System.out.println("End Element :" + qName); 

} 

public void characters(char ch[], int start, int length) 
     throws SAXException { 
    temp = ch; 

    if (tagFlag) { 
     builder.append(ch, start, length); 
    } 
} 

public String getInsideTag(String tag) { 
    this.tag = tag; 
    return insideTag; 
} 

} 
+0

您需要更好地定義輸入XML,特別地輸出所需因爲你的帖子根本就不清楚。看起來,你想要一些標籤保留,但其他人不要。同樣,如果XML非常大,那麼DOM可能不可行,因爲DOM需要在執行分析之前加載整個文檔模型。其他選項是SAX和StAX。 –

+0

感謝您編輯我的不良寫作。是的,我需要獲得標籤的內容。已經用我的SAX實現更新了我的帖子,但在某些情況下它不起作用。你能幫我解決我最新的問題嗎? –

回答

0

這個問題你代碼是你試圖記住通過傳遞給你的字符串的開始和結束位置方法。在拋出的異常中看到的內部標記的結果是在字符緩衝區的末尾附近開始,並在下一個字符緩衝區的開始附近結束。

使用SAX你需要他們提供或當你需要他們,他們佔據了臨時緩衝區可能被清除時,該字符複製。

最好的辦法是不記得在緩衝區中的位置,而是要創造startElementStringBuilder和字符添加到這一點,那麼得到完整的串出的建設者endElement

+0

我已經通過向StringBuilder添加字符來更改我的代碼,但問題是在字符()回調中我沒有訪問標記名的開始和標記名的結束!所以我必須像這樣改變StringBuilder參數:handler.append(ch,start - startTag.length,length + endTag.length).how我應該這樣做嗎? –

+0

您可以在start-和endElement方法中添加開始和結束標記。 – rsp

+0

我的問題解決了,謝謝你的幫助。 –

0

嘗試使用Digester,我幾年前,版本號1.5,它是簡單地創建一個像你這樣的XML映射。只是簡單的article如何使用沼氣池,但它是1.5版本,目前有3.0,我認爲最後一個版本包含了很多新的功能...

相關問題