1

编辑:这段代码很好。我在我的伪代码中不存在的某个地方发现了一个逻辑错误。我将其归咎于我缺乏 Java 经验。

在下面的伪代码中,我试图解析显示的 XML。也许是一个愚蠢的例子,但我的代码太大/太具体,任何人都无法从看到它并从发布的答案中学习得到任何真正的价值。所以,这更有趣,希望其他人和我一样可以从答案中学习。

我是 Java 新手,但我是一位经验丰富的 C++ 程序员,这让我相信我的问题在于我对 Java 语言的理解。

问题:当解析器完成时,我的向量充满了未初始化的奶牛。我创建了具有默认容量的奶牛向量(如果它类似于 C++ STL 向量,则不应该影响它的“大小”)。当我在解析后打印出 Cow Vector 的内容时,它给出了正确的 Vector 大小,但所有值似乎从未设置过。

信息:我已经使用其他没有 Vector字段的解析器成功完成了此操作,但在这种情况下,我想使用 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;
        }
    }
}
4

4 回答 4

3

当你说Cows未初始化时,String属性是否初始化为null?还是空字符串?

我知道你提到这是伪代码,但我只是想指出一些潜在的问题:

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

我假设您知道这一点,但实际上这个方法是使用带有开始和结束索引的字符缓冲区调用的。

另请注意,对于单个文本块,可以多次调用 characters(...),在每次调用中返回小块: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 等等)。

于 2008-10-26T09:11:19.353 回答
1

代码对我来说看起来不错。我说在每个函数的开头设置断点并在调试器中观察它或添加一些打印语句。我的直觉告诉我要么characters()没有被调用setColor(),要么setAge()不能正常工作,但这只是一个猜测。

于 2008-10-26T05:11:24.690 回答
0

我不得不说我不是这个设计的忠实粉丝。但是,您确定您的角色曾经被调用过吗?(也许一些 system.outs 会有所帮助)。如果它从未被调用,你最终会得到一头未初始化的牛。

另外,我不会尝试像这样自己实现 XML 解析器,因为您需要更加健壮地应对验证问题。

您可以使用 SAX 或 DOM4J,甚至更好的是,使用 Apache digester。

于 2008-10-26T05:17:34.710 回答
0

此外,如果我有一个模式,我将使用 JaxB 或其他代码生成器来加快 XML 接口代码的开发。代码生成器隐藏了直接使用 SAX 或 DOM4J 的许多复杂性。

于 2008-10-26T06:55:47.507 回答