Программа Java sax не переходит к методу startElement()

Я пытаюсь использовать синтаксический анализатор sax с настроенным DefaultHandler, но странно, что метод startElement() в dHandler никогда не вызывается. 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 {

        }

     } 

person Anton    schedule 10.06.2011    source источник
comment
кроме того, вы не должны использовать классы реализации sax, такие как DocumentImpl. Используйте интерфейс Документ.   -  person MeBigFatGuy    schedule 10.06.2011
comment
как ваш код компилируется в первую очередь? Ваша реализация DefaultHandler представляет собой анонимный локальный класс; ссылка на переменную total должна быть final.   -  person Vineet Reynolds    schedule 10.06.2011


Ответы (3)


Пожалуйста, проверьте оператор импорта для параметра Attribute, он должен быть:

import org.xml.sax.Attributes;

С Уважением

person aydaroos    schedule 15.08.2011
comment
Хорошо, первый выбор Eclipse для автозаполнения — java.util.jar; изменение ссылки устраняет проблему. - person htafoya; 11.04.2012

Возможно, вы неправильно переопределили значение по умолчанию startElement(). Если вы добавите аннотацию @Override к методу, вы не должны получить ошибку времени компиляции. Если вы это сделаете, то объявление startElement(...) (которое вы не показали) неверно.

РЕДАКТИРОВАТЬ: ваша декларация startElement должна выглядеть так:

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

Имена параметров могут быть разными, но количество аргументов и их типы должны точно совпадать.

person Jim Garrison    schedule 10.06.2011
comment
это именно то, что вы описали! я пытался добавить @Override раньше - и это дало мне ошибку. не могли бы вы подсказать, что изменить? - person Anton; 10.06.2011
comment
Пожалуйста, отредактируйте свой пост, чтобы показать, как вы объявили свой класс обработчика и объявление метода startElement(). Аннотация @Override поможет вам найти именно такую ​​проблему. Если вы думаете, что переопределяете что-то, это говорит вам, что вы не объявили это правильно. - person Jim Garrison; 10.06.2011
comment
я нигде его не объявлял — DefaultHandler — это класс адаптера, поэтому я просто переопределил методы. в DefaultHandler этот метод объявлен как: public void startElement (String uri, String localName, String qName, атрибуты Attributes), т.е. точно с теми же параметрами, которые я использовал. - person Anton; 10.06.2011
comment
Вы должны где-то расширить DefaultHandler. Это не адаптер, а абстрактный базовый класс, от которого вы должны создать подкласс, чтобы определить обработчик XML. Каково объявление класса, содержащего startElEment()? - person Jim Garrison; 10.06.2011
comment
вау, я пришел к решению, есть несколько типов классов атрибутов, и я импортировал неправильный (автоматически, в netbeans - вы знаете, просто щелкнув импорт, не задумываясь об этом). спасибо и всем откликнувшимся за помощь! Я ценю - person Anton; 10.06.2011
comment
В SO принято принимать ответ, который решает вашу проблему, щелкнув галочку рядом с ответом. - person Jim Garrison; 10.06.2011

Я думаю, вы имели в виду, что имя элемента — «состояние». Если это так, следующая строка в реализации 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 во внешнем классе, что сделало бы его неизменяемым (что делает операцию приращения недопустимой). Однако нельзя получить доступ к переменной total из-за пределов анонимного класса. Я бы предложил расширить класс DefaultHandler в другом классе и использовать эту реализацию обработчика, чтобы все было просто.

person Vineet Reynolds    schedule 10.06.2011
comment
да, я пробовал это - но он получает точно такой же результат, который я описал - Всего элементов: 0. он даже говорит Всего элементов: 0, когда я удаляю этот оператор if и оставляю только общее ++ - person Anton; 10.06.2011