2010-11-07 128 views
6

我在理解使用SAX解析XML結構時遇到了一些麻煩。比方說,有以下XML:SAX:如何獲取元素的內容

<root> 
    <element1>Value1</element1> 
    <element2>Value2</element2> 
</root> 

和一個字符串變量myString

剛開始使用方法startElement,endElement()和characters()很容易。但我不明白如何實現以下功能:

如果當前元素等於element1將其值value1存儲在myString中。據我瞭解有沒有像:

if (qName.equals("element1")) myString = qName.getValue(); 

想我只是想太複雜:-)

羅伯特

回答

6

有了SAX,您需要維護自己的堆棧。您可以很基本的處理做這樣的事情:

void startElement(...) { 
    if (name.equals("element1")) { 
     inElement1 = true; 
     element1Content = new StringBuffer(); 
    } 
} 

void characters(...) { 
    if (inElement1) { 
     element1Content.append(characterData); 
    } 
} 

void endElement(...) { 
    if (name.equals("element2")) { 
     inElement1 = false; 
     processElement1Content(element1Content.toString()); 
    } 
} 

如果你想代碼在你的榜樣,那麼你需要使用DOM模型而不是SAX。 DOM比較容易編碼,但通常比SAX速度更慢,內存更貴。

我推薦使用第三方庫而不是內置的Java XML庫進行DOM操作。 Dom4J看起來很不錯,但也有其他的庫可能。

+0

感謝卡梅隆,這是我預料:-)我的應用程序將在Android智能手機上運行,​​我認爲它更好地利用內置在SAX解析器中而不是切換到DOM。 – 2010-11-08 07:04:13

+0

也許使用首選的StringBuilder – 2013-02-11 14:03:20

6

你應該通過characters()記錄的內容,追加到了一個StringBuilder每次調用並僅在調用endElement()時存儲連接值。

爲什麼?由於characters()對於元素內容可以多次調用 - 每個調用引用該文本元素的連續子序列。

9

此解決方案適用於包含文本內容的單個元素。當element1有更多的子元素時,需要做更多的工作。布賴恩的評論非常重要。 當您有多個元素或想要更通用的解決方案時,這可能會對您有所幫助。我用300 + MB的XML文件測試,它仍然是非常快:

final StringBuilder builder=new StringBuilder(); 
XMLReader saxXmlReader = XMLReaderFactory.createXMLReader(); 

DefaultHandler handler = new DefaultHandler() { 
    boolean isParsing = false; 

    public void startElement(String uri, String localName, String qName, Attributes attributes) { 
     if ("element1".equals(localName)) { 
      isParsing = true; 
     } 
     if (isParsing) { 
      builder.append("<" + qName + ">"); 
     } 
    } 

    @Override 
    public void characters(char[] chars, int i, int i1) throws SAXException { 
     if (isParsing) { 
      builder.append(new String(chars, i, i1)); 
     } 
    } 

    @Override 
    public void endElement(String uri, String localName, String qName) throws SAXException { 
     if (isParsing) { 
      builder.append("</" + qName + ">"); 
     } 
     if ("element1".equals(localName)) { 
      isParsing = false; 
     } 
    } 
}; 

saxXmlReader.setContentHandler(handler); 
saxXmlReader.setErrorHandler(handler); 

saxXmlReader.parse(new InputSource(new FileInputStream(input))); 
相關問題