Java SAX解析器,存储属性

Java SAX解析器,存储属性,java,xml,sax,Java,Xml,Sax,我试图将当前文档位置存储在堆栈中,按下startElement,弹出endElement。现在我正在使用: public void startElement(String namespaceURI, String elname, String qName, Attributes atts) throws SAXException { original.append(innerText); original.append("<

我试图将当前文档位置存储在堆栈中,按下startElement,弹出endElement。现在我正在使用:

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));
....
public void startElement(字符串namespaceURI、字符串elname、,
字符串qName、属性atts)引发异常{
原始。追加(内部文本);
原件。附加(“”);
docStack.push(新StackElement(elname,atts));
....
不幸的是,当它稍后尝试读取ATT时,会出现错误: 原因:java.lang.IllegalStateException:属性只能在startElement()的范围内使用

是否有任何快速、可靠的方法来存储属性?
另外,有没有比为每个开始标记构造一个新的自定义对象堆栈元素更好的方法呢?

当您将属性推到自定义对象堆栈上时,您将获取实际的属性对象,根据下面的说明:

atts—附加到元素的属性。如果没有属性,则它应为空属性对象。startElement返回后此对象的值未定义。(强调我的)


相反,您应该在startElement(…)方法中捕获映射中的属性。这样,您可以在任何需要的地方使用它们。

如果
属性
是上下文敏感的,请在
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));
        }
    }
}
公共类堆栈元素{
私有映射映射=新的HashMap();
公共堆栈元素(字符串elname、属性atts){
对于(int i=0;i

p、 这可能看起来像是我剽窃了@nicholas的答案,但老实说,我已经把它打印出来了,并且在他发帖时正在编写代码。

我曾想过把所有东西都复制到那样的地图上,但我认为这可能会效率低下,特别是因为我不需要每个元素上的所有属性。这样会更慢,since它正在构造两个新类,构造一个新的StackElement和HashMap,并在每个元素上查询所有属性!我的问题是,有没有更有效的方法来做到这一点,也许是“冻结”属性和添加到StackElement?getQName应该是GetLocalName这似乎有点慢,使用每个startElement构造对象,但即使有这种开销,它仍然应该比DOM高效得多,对吗?它肯定比DOM更高效,因为您不会存储所有内容,只存储一些精简的内容我认为你对创建对象的担心是没有根据的,因为java不是一种缓慢而笨拙的语言。一旦你完成解析,内存和对象就会被清理掉。这个可以真正咬你。我有一个文件,里面有500米,中间的某个地方(10分钟+处理后)就失败了。.我只是在缓存attributes对象,以便在endElement函数中使用(因为我的模型对象需要元素文本和属性)。结果证明它是有效的…有一段时间…我想阅读细节是很重要的。除了
映射
,您还可以使用
org.xml.sax.helpers.AttributesImpl
,它的构造函数采用
属性
对象。开销可能类似。