Domanda

Modifica: questo codice va bene. Ho trovato un bug logico da qualche parte che non esiste nel mio pseudo codice. Lo stavo dando la colpa alla mia mancanza di esperienza Java.

Nel pseudo codice di seguito, sto cercando di analizzare l'XML mostrato. Un esempio sciocco forse ma il mio codice era troppo grande / specifico per chiunque per ottenere un valore reale dal vederlo e imparare dalle risposte pubblicate. Quindi, questo è più divertente e spero che altri possano imparare dalla risposta come me.

Sono nuovo di Java, ma un programmatore C ++ esperto che mi fa credere che il mio problema risieda nella mia comprensione del linguaggio Java.

Problema: quando termina il parser, il mio vettore è pieno di mucche non inizializzate. Creo il Vector of Cows con una capacità predefinita (che non dovrebbe influire sulla sua & Quot; size & Quot; se è qualcosa come C ++ STL Vector). Quando stampo il contenuto di Cow Vector dopo l'analisi, dà la giusta dimensione di Vector ma tutti i valori sembrano non essere mai stati impostati.

Info: l'ho fatto con successo con altri parser che non hanno campi in Vector ma in questo caso, vorrei usare un Vector per accumulare proprietà Cow.

MoreInfo: non posso usare generici (Vector < Cow >) quindi per favore non indicarmi lì. :)

Grazie in anticipo.

<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;
        }
    }
}
È stato utile?

Soluzione

Il codice mi sembra perfetto. Dico impostare punti di interruzione all'inizio di ogni funzione e guardarlo nel debugger o aggiungere alcune dichiarazioni di stampa. Il mio istinto mi dice che o characters() non viene chiamato o setColor() e setAge() non funzionano correttamente, ma è solo una supposizione.

Altri suggerimenti

Quando dici che le mucche non sono inizializzate, le proprietà String sono inizializzate su null? O stringhe vuote?

So che hai detto che questo è pseudo-codice, ma volevo solo sottolineare alcuni potenziali problemi:

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

Dovresti davvero usare tag.equals (...) invece di tag == ... qui.

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

Suppongo che tu ne sia consapevole, ma in realtà questo metodo viene chiamato con un buffer di caratteri con indici di inizio e fine.

Nota anche che i caratteri (...) possono essere chiamati più volte per un singolo blocco di testo, restituendo piccoli blocchi in ogni chiamata: http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters (char [],% 20int,% 20int)

  

" ... I parser SAX possono restituire tutti contigui   dati di carattere in un singolo blocco, o   possono dividerlo in più pezzi ... "

Dubito che incontrerai quel problema nel semplice esempio che hai fornito, ma hai anche detto che questa è una versione semplificata di un problema più complesso. Se nel tuo problema originale, il tuo XML è costituito da grandi blocchi di testo, questo è qualcosa da considerare.

Infine, come altri hanno già detto, se potessi, è una buona idea considerare una libreria di marshalling XML (ad esempio, JAXB, Castor, JIBX, XMLBeans, XStream per citarne alcuni).

Devo dire che non sono un grande fan di questo design. Tuttavia, sei sicuro che i tuoi personaggi vengano mai chiamati? (forse alcuni system.outs sarebbero d'aiuto). Se non viene mai chiamato, finiresti con una mucca non inizializzata.

Inoltre, non tenterei di implementare un parser XML in questo modo poiché è necessario essere più robusti rispetto ai problemi di convalida.

Puoi usare SAX o DOM4J, o ancora meglio, usare il digestore Apache.

Inoltre, se ho uno schema, userò JaxB o un altro generatore di codice per accelerare lo sviluppo del codice dell'interfaccia XML. I generatori di codice nascondono gran parte della complessità di lavorare direttamente con SAX o DOM4J.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top