Аккумулятор Java Vector Field (private member) не хранит моих коров!

StackOverflow https://stackoverflow.com/questions/237561

  •  04-07-2019
  •  | 
  •  

Вопрос

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

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

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

Проблема: Когда анализатор завершает работу, мой Вектор полон неинициализированных коров. Я создаю Vector of Cows с емкостью по умолчанию (которая не должна влиять на & Quot; size & Quot; если это что-то вроде C ++ STL 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;
        }
    }
}
Это было полезно?

Решение

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

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

Когда вы говорите, что коровы неинициализированы, свойства 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 [],% 20int,% 20int)

  

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top