2010-11-07 111 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))); 
相关问题