Question

Edit: Ce code est correct. J'ai trouvé un bogue logique quelque part qui n'existe pas dans mon pseudo-code. Je le blâmais sur mon manque d’expérience Java.

Dans le pseudo-code ci-dessous, j'essaie d'analyser le code XML présenté. Un exemple ridicule peut-être, mais mon code était trop volumineux / spécifique pour que quiconque puisse tirer un avantage réel de sa visualisation et de l’apprentissage des réponses postées. C'est donc plus divertissant et j'espère que d'autres pourront tirer des leçons de la réponse aussi bien que moi.

Je suis nouveau sur Java mais je suis un programmeur C ++ expérimenté qui me fait croire que mon problème réside dans ma compréhension du langage Java.

Problème: à la fin de l’analyseur, mon vecteur est rempli de vaches non initialisées. Je crée le vecteur de vaches avec une capacité par défaut (ce qui ne devrait pas affecter sa & "Taille &" S'il s'agit de quelque chose comme C ++ STL Vector). Lorsque j'imprime le contenu du vecteur Vache après l'analyse, il indique la taille appropriée du vecteur, mais toutes les valeurs ne semblent jamais avoir été définies.

Info: j’ai réussi à le faire avec d’autres analyseurs qui n’ont pas de champs de vecteur mais , mais dans ce cas, j'aimerais utiliser un vecteur pour accumuler les propriétés de la vache.

MoreInfo: Je ne peux pas utiliser de médicaments génériques (Vecteur < Vache >), veuillez donc ne pas me diriger là-bas. :)

Merci d'avance.

<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;
        }
    }
}
Était-ce utile?

La solution

Le code me semble bien. Je dis de définir des points d'arrêt au début de chaque fonction et de les regarder dans le débogueur ou d'ajouter des instructions d'impression. Mon instinct me dit que characters() n'est pas appelé ou setColor() et setAge() ne fonctionne pas correctement, mais ce n'est qu'une hypothèse.

Autres conseils

Lorsque vous dites que les vaches ne sont pas initialisées, les propriétés de la chaîne sont-elles initialisées à null? Ou des chaînes vides?

Je sais que vous avez mentionné qu'il s'agissait d'un pseudo-code, mais je voulais simplement signaler quelques problèmes potentiels:

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

Vous devriez vraiment utiliser tag.equals (...) au lieu de tag == ... ici.

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

Je suppose que vous en êtes conscient, mais cette méthode est en fait appelée avec un tampon de caractères avec les index de début et de fin.

Notez également que les caractères (...) peuvent être appelés plusieurs fois pour un seul bloc de texte, renvoyant de petits morceaux à chaque appel: http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters (char [],% 20int,% 20int)

  

& "; ... Les analyseurs syntaxiques SAX peuvent renvoyer tous les éléments contigus   données de caractère dans un seul morceau, ou   ils peuvent le scinder en plusieurs morceaux ... & ";

Je doute que vous rencontriez ce problème dans l'exemple simple que vous avez fourni, mais vous avez également mentionné qu'il s'agit d'une version simplifiée d'un problème plus complexe. Si, dans votre problème initial, votre code XML se compose de gros blocs de texte, vous devez en tenir compte.

Enfin, comme d’autres l’ont mentionné, si vous le pouviez, il est judicieux d’envisager une bibliothèque de triage XML (par exemple, JAXB, Castor, JIBX, XMLBeans, XStream, pour en nommer quelques-unes).

Je dois dire que je ne suis pas un grand fan de ce design. Cependant, êtes-vous sûr que vos personnages sont appelés? (Peut-être que quelques system.outs pourraient aider). Si ce n'est jamais appelé, vous vous retrouverez avec une vache non initialisée.

En outre, je ne voudrais pas implémenter un analyseur XML de cette manière, car vous devez être plus robuste face aux problèmes de validation.

Vous pouvez utiliser SAX ou DOM4J, ou mieux, utiliser Apache Digester.

De plus, si j’ai un schéma, j’utiliserai JaxB ou un autre générateur de code pour accélérer le développement du code d’interface XML. Les générateurs de code cachent une grande partie de la complexité liée au travail direct avec SAX ou DOM4J.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top