Java SAX解析器,存储属性

问题描述:

我试图将当前文档位置存储在堆栈中,推送startElement,弹出endElement。现在,我使用:Java SAX解析器,存储属性

public void startElement(String namespaceURI, String elname, 
         String qName, Attributes atts) throws SAXException { 
    original.append(innerText); 
    original.append("<"); 
    original.append(elname); 
    original.append(">"); 
    docStack.push(new StackElement(elname,atts)); 
.... 

不幸的是当它试图在以后阅读的ATT,它提供了错误: 致:java.lang.IllegalStateException:属性只能的startElement的范围内使用() 。

是否有任何快速可靠的方法来存储属性? 另外,是否有更好的方法来做到这一点比为每个开始标记构造一个新的自定义对象StackElement?

当你按下属性到您的自定义对象堆栈,你是采取实际属性对象,该对象,根据documentation这样说:

的ATT - 连接到元素的属性。如果没有属性,它应该是一个空的属性对象。 这个对象的startElement返回后的价值是不确定的(重点煤矿)

而应该在你的startElement(...)方法捕获在地图<字符串,字符串>属性。这样你就可以在任何你想要的地方使用它们。

+0

伟大的思想认为一样:) – Bohemian 2011-06-13 23:20:36

+0

似乎会有点慢,用每个startElement构造对象,但即使有这个开销,它仍然应该比DOM更有效率,是正确的吗? – NoBugs 2011-06-14 00:46:27

+1

它肯定会比DOM更高效,因为你不会存储所有东西,只是一些东西。我认为你对对象创建的担忧是没有根据的,因为Java并不是一种缓慢而笨拙的语言。无论如何,解析完内存和对象都会被清理干净。 – 2011-06-14 01:01:05

如果Attributes是上下文敏感的,请在StackElement构造函数中从它们中提取您需要的内容(并且不要存储该引用)。

像这样的事:

public class StackElement { 

    private Map<String, String> map = new HashMap<String, String>(); 

    public StackElement(String elname, Attributes atts) { 

     for (int i = 0; i < atts.getLength(); i++) { 
      map.put(atts.getQName(i),atts.getValue(i)); 
     } 
    } 
} 

附:这可能看起来像我剽窃@尼古拉斯的答案,但说实话,我已经输入了它,并在他发布时正在编写代码。

+0

+1 Plagarism! :) – 2011-06-13 22:55:32

+0

我曾经想过把所有东西都拷贝到地图上,但我认为这可能效率不高,特别是因为我不需要每个元素上的所有属性。这会慢一点,因为它在每个元素上创建了两个新类的构造,构造了一个新的StackElement和HashMap,并查询了所有的属性!我的问题是,是否有更有效的方式来做到这一点,也许“冻结”的属性并添加到StackElement? – NoBugs 2011-06-13 23:21:18

+0

get getQName应该是getLocalName – NoBugs 2011-06-14 19:38:57