【问题标题】:java sax program doesn't go to startElement() methodjava sax 程序不去 startElement() 方法
【发布时间】:2011-06-10 03:27:19
【问题描述】:

我正在尝试将 sax 解析器与自定义的 DefaultHandler 一起使用,但奇怪的是 dHandler 中的 startElement() 方法从未被调用。 endDocument() 可以正常工作,但会打印

Total elements:0

而我的 xml 文件有 11 个“状态”类型的元素。

即使我将 total++ 放在 if 语句之外,所以每次调用 startElement() 时它都会递增,它仍然显示 0 个元素。

请帮帮我,谢谢

if(e.getSource()==open)
    {
        JFileChooser chooseFile=new JFileChooser();
        int returnVal = chooseFile.showOpenDialog(wnd);
         if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = chooseFile.getSelectedFile();

                //This is where a real application would open the file.
                parser.parse(new InputSource(new FileInputStream(file)));
                DocumentImpl document = (DocumentImpl)parser.getDocument();
                Node root = document.getLastChild();
                AllElements allelements = new AllElements();
                NodeIteratorImpl iterator =(NodeIteratorImpl)document.createNodeIterator(root,
        NodeFilter.SHOW_ELEMENT, (NodeFilter)allelements, true);
                Node n;
                states.removeAll(states);
                while ((n = iterator.nextNode()) != null)
                {

                    if(n.getNodeName().equals("state"))
                    {
                        NamedNodeMap attrs = n.getAttributes();
                        NodeList children=n.getChildNodes();
                        State newState=new State(attrs.item(0).getNodeValue(),
                                attrs.item(1).getNodeValue(),attrs.item(2).getNodeValue(),attrs.item(3).getNodeValue(),children.item(0).getTextContent());
                        states.add(newState);

                    }

                }
                Collections.sort(states,new StateComparator());
                mod.setRowCount(states.size());
                mod.setColumnCount(5);
                for(int i=0;i<states.size();i++)
                {
                    mod.setValueAt(states.get(i).abbr, i, 0);

                    mod.setValueAt(states.get(i).name, i, 1);
                    mod.setValueAt(states.get(i).population_2k10, i, 2);
                    mod.setValueAt(states.get(i).rank_2k, i, 3);
                    mod.setValueAt(states.get(i).census_1990, i, 4);
                }

                mean=0;
                max=MAXIMUM;
                min=MINIMUM;
                count=0;
                  total=0;
                  SAXParserFactory parserFact = SAXParserFactory.newInstance();
        SAXParser parserS = parserFact.newSAXParser();
        DefaultHandler dHandler = new DefaultHandler(){
            public void startElement(String uri, String name, String element, Attributes atri)
                            {
                if (element.equals("state")){
                    total++;
                }
            }
            public void endDocument(){
                System.out.println("Total elements: " + total);
            }
        };
                  parserS.parse(file, dHandler);
                  meanL.setText("mean="+mean);
                  maxL.setText("max="+max);
                  minL.setText("min="+min);
                  countL.setText("count="+total);
        } else {

        }

     } 

【问题讨论】:

  • 顺便说一句,您不应该使用 sax 的实现类,例如 DocumentImpl。使用界面文档。
  • 你的代码首先是如何编译的?您的 DefaultHandler 实现是一个匿名本地类;其中引用的total 变量必须是final

标签: java xml sax


【解决方案1】:

请检查属性参数的导入语句,应该是:

import org.xml.sax.Attributes;

问候

【讨论】:

  • 不错,Eclipse 自动完成的首选是 java.util.jar;更改参考可以解决问题。
【解决方案2】:

也许你没有正确覆盖默认的startElement()。如果您在方法中添加@Override 注释,则不应出现编译时错误。如果你这样做了,那么startElement(...)(你没有显示)的声明是不正确的。

编辑:您的 startElement 声明需要如下所示:

void startElement(
    String uri, 
    String localName, 
    String qName, 
    Attributes attributes) 

参数名称可以不同,但​​参数数量及其类型必须完全匹配。

【讨论】:

  • 这正是您所描述的!我之前曾尝试添加@Override - 它给了我错误。你能告诉我要改变什么吗?
  • 请编辑您的帖子以显示您如何声明您的处理程序类,以及startElement() 方法的声明。 @Override 注释可以帮助您准确找到此类问题。如果您认为您正在覆盖某些内容,它会告诉您您是否没有正确声明它。
  • 我没有在任何地方声明它 - DefaultHandler 是一个适配器类,所以我只是重新定义了方法。在 DefaultHandler 中,此方法声明为:public void startElement (String uri, String localName, String qName, Attributes attributes),即与我使用的参数完全相同。
  • 您必须在某处扩展 DefaultHandler。它不是一个适配器,而是一个抽象基类,您必须将其子类化以定义您的 XML 处理程序。包含startElEment() 的类的声明是什么?
  • 哇,我找到了解决方案,有几种类型的属性类,我导入了错误的一种(自动,在 netbeans 中 - 你知道,只需单击导入就可以了)。感谢您和所有响应帮助的人!我很感激
【解决方案3】:

我认为您的意思是元素的名称是“状态”。如果是这样, DefaultHandler.startElement 实现中的以下行应该是:

if (name.equals("state")){
    total++;
}

而不是

if (element.equals("state")){
    total++;
}

startElement 方法的第三个参数实际上是 qName。如果不存在命名空间前缀,它将为空;如果存在前缀,则会填充它。

编辑

原始代码似乎不会编译,至少不会针对我使用的 Oracle/Sun Java 6 编译器进行编译。如果要计算总元素,那么 DefaultHandler 类的实现应该是这样的:

DefaultHandler handler = new DefaultHandler() {

    public int total = 0;

    public void startElement(String uri, String name, String qName,
            Attributes atri) {
        if (qName.equals("state")) {
            total++;
        }
    }

    public void endDocument() {
        System.out.println("Total elements: " + total);
    }
};

请注意,total 变量现在是匿名类的成员。如果不是,则必须在外部类中将其声明为 final,这将使其不可变(将递增操作视为非法)。但是,不能从匿名类外部访问总变量。我建议在不同的类中扩展 DefaultHandler 类,并使用该处理程序实现,以保持简单。

【讨论】:

  • 是的,我已经尝试过了 - 但它得到的结果与我描述的完全相同 - “总元素:0”。当我删除这个 if 语句并只留下 total++ 时,它甚至会说“总元素:0”
猜你喜欢
  • 2017-08-14
  • 2012-06-11
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多