Аккумулятор Java Vector Field (частный член) не хранит моих коров!

Обновлено: этот код в порядке. Я обнаружил где-то логическую ошибку, которой нет в моем псевдокоде. Я обвинял это в том, что у меня не было опыта работы с Java.

В псевдокод ниже я пытаюсь проанализировать показанный XML. Может быть, это глупый пример, но мой код был слишком большим / конкретным, чтобы кто-либо мог получить реальную пользу от его просмотра и изучения опубликованных ответов. Так что это более занимательно, и, надеюсь, другие смогут извлечь уроки из ответа так же, как и я.

Я новичок в Java, но опытный программист на C++, что заставляет меня думать, что моя проблема заключается в моем понимании языка Java.

Проблема: когда парсер завершает работу, мой вектор заполнен неинициализированными коровами. Я создаю вектор коров с емкостью по умолчанию (что не должно влиять на его "размер", если это что-то вроде вектора C++ STL). Когда я распечатываю содержимое вектора коровы после синтаксического анализа, он дает правильный размер вектора, но все значения, похоже, никогда не были установлены.

Информация: я успешно проделал это с другими парсерами, у которых нет Vector поля, но в этом случае я бы хотел использовать Vector для накопления свойств Cow.

MoreInfo: Я не могу использовать дженерики (Vector <Cow>), поэтому, пожалуйста, не указывайте мне на них. :)

Заранее спасибо.

<pluralcow>
        <cow>
            <color>black</color>
            <age>1</age>
        </cow>
        <cow>
            <color>brown</color>
            <age>2</age>
        </cow>
        <cow>
            <color>blue</color>
            <age>3</age>
        </cow>
</pluralcow>

public class Handler extends DefaultHandler{
    // vector to store all the cow knowledge
    private Vector  m_CowVec;

    // temp variable to store cow knowledge until
    // we're ready to add it to the vector
    private Cow     m_WorkingCow;

    // flags to indicate when to look at char data
    private boolean m_bColor;
    private boolean m_bAge;

    public void startElement(...tag...)
    {
        if (tag == pluralcow){   // rule: there is only 1 pluralcow tag in the doc
                // I happen to magically know how many cows there are here.             
                m_CowVec = new Vector(numcows);
        }else if (tag == cow ){  // rule: multiple cow tags exist
            m_WorkingCow = new Cow();
        }else if (tag == color){ // rule: single color within cow
            m_bColor = true;
        }else if (tag == age){   // rule: single age within cow
            m_bAge = true;
        }
    }

    public void characters(...chars...)
    {
        if (m_bColor){
            m_WorkingCow.setColor(chars);   
        }else if (m_bAge){
            m_WorkingCow.setAge(chars);
        }
    }

    public void endElement(...tag...)
    {
        if (tag == pluralcow){
            // that's all the cows
        }else if (tag == cow ){
            m_CowVec.addElement(m_WorkingCow);      
        }else if (tag == color){
            m_bColor = false;
        }else if (tag == age){
            m_bAge = false;
        }
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
1 275
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Код мне нравится. Я говорю устанавливать точки останова в начале каждой функции и смотреть ее в отладчике или добавлять операторы печати. Моя интуиция подсказывает мне, что либо characters() не вызывается, либо setColor() и setAge() работают некорректно, но это только предположение.

Должен сказать, что я не большой поклонник этого дизайна. Однако вы уверены, что ваших персонажей когда-нибудь называют? (возможно, поможет несколько system.out). Если он никогда не вызывается, вы получите неинициализированную корову.

Кроме того, я бы не стал пытаться реализовать подобный XML-анализатор, поскольку вам нужно быть более устойчивым к проблемам проверки.

Вы можете использовать SAX или DOM4J или, что еще лучше, использовать дайджест Apache.

У вас есть ссылки на синтаксический анализатор SAX в Java? Я пишу для Blackberry, так что маленькие и быстрые - главные приоритеты.

JR Lawhorne 26.10.2008 08:26

Кроме того, это переопределение org.xml.sax.helpers.DefaultHandler

JR Lawhorne 26.10.2008 08:30

Он выглядел как стандартный синтаксический анализатор, но я не был уверен, был ли это реальный класс или это был отдельный перевод из синтаксического анализатора C++ SAX ... Я все еще думаю, что вам нужно что-то, что может обрабатывать беспорядочный XML, если вы не уверены, что это подтверждено. Попробуйте посмотреть на дигестор apache ...

Uri 26.10.2008 18:06

Кроме того, если у меня есть схема, я буду использовать JaxB или другой генератор кода, чтобы ускорить разработку кода интерфейса XML. Генераторы кода скрывают большую часть сложности работы непосредственно с SAX или DOM4J.

Когда вы говорите, что коровы не инициализированы, инициализируются ли свойства String нулевым значением? Или пустые строки?

Я знаю, что вы упомянули, что это псевдокод, но я просто хотел указать на несколько потенциальных проблем:

public void startElement(...tag...)
    {
        if (tag == pluralcow){   // rule: there is only 1 pluralcow tag in the doc
                // I happen to magically know how many cows there are here.                     
                m_CowVec = new Vector(numcows);
        }else if (tag == cow ){  // rule: multiple cow tags exist
                m_WorkingCow = new Cow();
        }else if (tag == color){ // rule: single color within cow
                m_bColor = true;
        }else if (tag == age){   // rule: single age within cow
                m_bAge = true;
        }
    }

Вам действительно стоит использовать здесь tag.equals (...) вместо tag == ...

public void characters(...chars...)
{
    if (m_bColor){
            m_WorkingCow.setColor(chars);   
    }else if (m_bAge){
            m_WorkingCow.setAge(chars);
    }
}

Я предполагаю, что вы знаете об этом, но на самом деле эти методы вызываются с символьным буфером с начальным и конечным индексами.

Также обратите внимание, что символы (...) могут вызываться несколько раз для одного текстового блока, возвращая небольшие фрагменты при каждом вызове: http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters(char[****************************************************

"...SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks..."

Я сомневаюсь, что вы столкнетесь с этой проблемой в приведенном вами простом примере, но вы также упомянули, что это упрощенная версия более сложной проблемы. Если в вашей исходной задаче ваш XML состоит из больших текстовых блоков, это следует учитывать.

Наконец, как уже упоминалось другими, если вы могли бы, было бы неплохо рассмотреть библиотеку маршалинга XML (например, JAXB, Castor, JIBX, XMLBeans, XStream, чтобы назвать несколько).

Отличный ответ! 1) Буфер символов: да, я упрощал псевдокод. 2) String.equals (): да, тоже упрощение. 3) символы () вызываются несколько раз: отличное примечание! Я должен быть уверен, что займусь этим делом. 4) Еще не нашел библиотеки маршалинга, которая работает на Blackberry JDE 4 (J2ME).

JR Lawhorne 26.10.2008 20:51

Ах, я не знал, что вы программируете для J2ME. Тогда это немного отличается, и, вероятно, вам будет полезно избежать этого дополнительного уровня абстракции и связанных с этим накладных расходов на обработку.

Jack Leow 27.10.2008 01:11

Другие вопросы по теме