Pregunta

Editar:Este código está bien.He encontrado un error de lógica en algún lugar que no existe en mi pseudo código.Estaba echándole la culpa a mi falta de Java experiencia.

En el pseudo-código a continuación, voy a tratar de analizar el XML de muestra.Un ejemplo tonto, pero tal vez mi código era demasiado grande/específico para que cualquiera pueda obtener cualquier valor real de ver y aprender de las respuestas publicadas.Así que, esto es más entretenido y espero que otros puedan aprender de la respuesta tan bien como a mí.

Soy nuevo en Java pero un experimentado programador de C++ que me hace creer que mi problema radica en que mi comprensión del lenguaje Java.

Problema:Cuando el analizador acabados, mi Vector está llena de sin inicializar las Vacas.Puedo crear el Vector de las Vacas con una capacidad predeterminada (que no debería efecto es el "tamaño" si es algo como C++ Vector STL).Al imprimir el contenido de la Vaca Vector a cabo tras el análisis, se da el derecho tamaño del Vector, pero todos los valores aparecen nunca se han establecido.

Info:He hecho esto con éxito con otros analizadores que no tiene Vector campos pero en este caso, me gustaría utilizar un Vector para acumular propiedades de Vaca.

MoreInfo:No se pueden utilizar medicamentos genéricos (Vector< Vaca >) así que por favor no me apunto allí.:)

Gracias de antemano.

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

Solución

El código se ve bien para mí.Yo digo establecer puntos de interrupción en el inicio de cada función y ver que en el depurador o agregar algunas instrucciones de impresión.Mi instinto me dice que ya sea characters() no se llama o setColor() y setAge() no funcionan correctamente, pero eso es sólo una conjetura.

Otros consejos

Cuando dice que las vacas no están inicializadas, ¿las propiedades de la cadena se inicializan como nulas? ¿O cadenas vacías?

Sé que mencionaste que este es un seudocódigo, pero solo quería señalar algunos problemas potenciales:

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

Realmente deberías usar tag.equals (...) en lugar de tag == ... aquí.

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

Supongo que está al tanto de esto, pero este método en realidad se llama con un búfer de caracteres con índices de inicio y fin.

Tenga en cuenta también que los caracteres (...) se pueden invocar varias veces para un solo bloque de texto, devolviendo pequeños fragmentos en cada llamada: http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters (char [],% 20int,% 20int)

  

" ... los analizadores SAX pueden devolver todo contiguo   datos de caracteres en un solo fragmento, o   pueden dividirlo en varios trozos ... "

Dudo que se encuentre con ese problema en el ejemplo simple que proporcionó, pero también mencionó que esta es una versión simplificada de un problema más complejo. Si en su problema original, su XML consiste en bloques de texto grandes, esto es algo a considerar.

Finalmente, como otros han mencionado, si pudiera, es una buena idea considerar una biblioteca de clasificación XML (por ejemplo, JAXB, Castor, JIBX, XMLBeans, XStream, por nombrar algunos).

Tengo que decir que no soy un gran admirador de este diseño. Sin embargo, ¿estás seguro de que alguna vez se llama a tus personajes? (tal vez algunos system.outs ayudarían). Si nunca se llama, terminarías con una vaca no inicializada.

Además, no trataría de implementar un analizador XML de esta manera, ya que debe ser más robusto frente a los problemas de validación.

Puedes usar SAX o DOM4J, o incluso mejor, usar el digestor Apache.

Además, si tengo un esquema, usaré JaxB u otro generador de código para acelerar el desarrollo del código de interfaz XML. Los generadores de código ocultan gran parte de la complejidad de trabajar directamente con SAX o DOM4J.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top