Pergunta

Edit: Este código é bom. Eu encontrei um lugar lógica bug que não existe no meu código pseudo. Eu estava culpando-o em minha falta de experiência Java.

No código pseudo abaixo, eu estou tentando analisar o XML mostrado. Um exemplo bobo, mas talvez meu código era muito grande / específico para qualquer um obter qualquer valor real fora de vê-lo e aprender com respostas postadas. Então, isso é mais divertido e espero que outros possam aprender com a resposta, assim como eu.

Eu sou novo para Java, mas um programador experiente C ++ que me faz acreditar que minhas mentiras problema na minha compreensão da linguagem Java.

Problema: Ao terminar o analisador, o meu vetor está cheio de vacas não inicializadas. I criar o vetor de Vacas com uma capacidade padrão (que não deve efetivá-la de "tamanho" Se é qualquer coisa como C ++ STL Vector). Quando eu imprimir o conteúdo da Cow Vector após a análise, ele dá o tamanho certo da Vector mas todos os valores aparecem nunca foram definidos.

Info:. Eu tenho feito isso com sucesso com outros analisadores que não têm Vector campos , mas neste caso, eu gostaria de usar um vetor para propriedades vaca acumular

MoreInfo: Eu não posso usar os genéricos (Vector ) então por favor não me aponte lá. :)

Agradecemos antecipadamente.

<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;
        }
    }
}
Foi útil?

Solução

O código parece bem para mim. Eu digo pontos de interrupção definido no início de cada função e vê-lo no depurador ou adicionar algumas declarações de impressão. Meu instinto me diz que quer characters() não está sendo chamado ou setColor() e setAge() não funcionam corretamente, mas isso é apenas um palpite.

Outras dicas

Quando você diz que as vacas são não inicializadas, são as propriedades de cadeia inicializado para nulo? Ou esvaziar Cordas?

Eu sei que você mencionou que este é pseudo-código, mas eu só queria salientar alguns problemas potenciais:

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;
        }
    }

Você realmente deve estar usando tag.equals (...) em vez de tag == ... aqui.

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

Eu estou supondo que você está ciente disso, mas estes métodos é realmente chamado com um buffer de caracteres com índices iniciais e finais.

Note-se também que os personagens (...) pode ser chamado várias vezes para um único bloco de texto, retornando pequenos pedaços em cada chamada: http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters (char [],% 20int, 20int%)

" ... analisadores SAX pode retornar todos contígua dados de caracteres em um único pedaço, ou eles podem dividi-lo em vários pedaços ... "

Eu duvido que você vai correr em que problema no exemplo simples que você forneceu, mas você também mencionou que esta é uma versão simplificada de um problema mais complexo. Se em seu problema original, o XML é composto por grandes blocos de texto, isso é algo a considerar.

Finalmente, como já foi mencionado, se pudesse, é uma boa ideia a considerar uma biblioteca de triagem XML (por exemplo, JAXB, Castor, jibx, XMLBeans, XStream para citar alguns).

Eu tenho que dizer que eu não sou um grande fã deste projeto. No entanto, você tem certeza que seus personagens nunca é chamado? (Talvez algumas system.outs ajudaria). Se ele nunca é chamado, você iria acabar com uma vaca não inicializado.

Além disso, eu não iria tentar implementar um parser XML me assim desde que você precisa ser mais firme contra problemas de validação.

Você pode usar SAX ou dom4j, ou melhor ainda, o uso Apache digestor.

Além disso, se eu tenho um esquema vou usar JAXB, ou de outro gerador de código para acelerar o desenvolvimento de código de interface XML. Os geradores de código esconder um monte da complexidade de trabalhar diretamente com SAX ou dom4j.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top