Java SAX:如何获取元素的内容
我在理解用SAX解析XML结构时遇到一些困难。假设存在以下XML:Java SAX:如何获取元素的内容,java,xml,sax,Java,Xml,Sax,我在理解用SAX解析XML结构时遇到一些困难。假设存在以下XML: <root> <element1>Value1</element1> <element2>Value2</element2> </root> 我想我只是想得太复杂了:-) Robert您应该通过characters()记录内容,为每次调用附加到StringBuilder,并且只在endElement()调用时存储连接的值 为什么??因为元素内容可以
<root>
<element1>Value1</element1>
<element2>Value2</element2>
</root>
我想我只是想得太复杂了:-)
Robert您应该通过
characters()
记录内容,为每次调用附加到StringBuilder,并且只在endElement()
调用时存储连接的值
为什么??因为元素内容可以多次调用
characters()
,每次调用都引用该文本元素的连续子序列。使用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更慢,内存更昂贵
我建议使用第三方库而不是内置的JavaXML库来进行DOM操作。Dom4J看起来不错,但可能还有其他库。此解决方案适用于包含文本内容的单个元素。当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)));
final StringBuilder=新StringBuilder();
XMLReader saxXmlReader=XMLReaderFactory.createXMLReader();
DefaultHandler=新的DefaultHandler(){
布尔值isParsing=false;
public void startElement(字符串uri、字符串localName、字符串qName、属性){
if(“element1”.equals(localName)){
isParsing=真;
}
如果(isParsing){
生成器。追加(“”);
}
}
@凌驾
公共无效字符(char[]chars,int i,int i1)引发异常{
如果(isParsing){
append(新字符串(chars,i,i1));
}
}
@凌驾
public void endElement(字符串uri、字符串localName、字符串qName)引发SAXException{
如果(isParsing){
生成器。追加(“”);
}
if(“element1”.equals(localName)){
isParsing=false;
}
}
};
setContentHandler(handler);
setErrorHandler(handler);
parse(新的InputSource(新的FileInputStream(input));
谢谢Cameron,这正是我所期望的:-)由于我的应用程序将在Android智能手机上运行,我认为使用内置SAX解析器比切换到DOM更好。也许可以使用首选的StringBuilder
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)));