Java Vector Field(私有成员)累加器不存储我的Cows!
题
编辑:这段代码很好。我在伪代码中找不到某个逻辑错误。我把它归咎于我缺乏Java经验。
在下面的伪代码中,我正在尝试解析显示的XML。一个愚蠢的例子可能,但是我的代码太大/特定,任何人都无法从看到它并从发布的答案中学习获得任何真正的价值。所以,这更有趣,希望其他人也可以从答案中学习。
我是Java的新手,但是经验丰富的C ++程序员让我相信我的问题在于我对Java语言的理解。
问题:当解析器完成时,我的Vector充满了未初始化的Cows。我使用默认容量创建了Vector of Cows(它不应该影响它的<!> quot; size <!>;如果它像C ++ STL Vector那样)。当我在解析后打印Cow Vector的内容时,它会给出正确大小的Vector,但所有值都不会被设置。
信息:我已成功完成了其他没有Vector 字段的解析器,但在这种情况下,我想使用Vector来累积Cow属性。
MoreInfo:我不能使用泛型(Vector <!> lt; Cow <!> gt;)所以请不要指向我。 :)
提前致谢。
<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;
}
}
}
解决方案
代码看起来很好。我说在每个函数的开头设置断点并在调试器中观察它或添加一些打印语句。我的直觉告诉我,characters()
未被调用或setColor()
且setAge()
无法正常工作,但这只是猜测。
其他提示
当您说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 == ... here。
public void characters(...chars...)
{
if(m_bColor){
m_WorkingCow.setColor(chars);
}else if(m_bAge){
m_WorkingCow.setAge(chars);
}
}
我假设您已经意识到这一点,但实际上这个方法是使用带有开始和结束索引的字符缓冲区调用的。
另请注意,对于单个文本块,可以多次调用字符(...),在每次调用中返回小块: 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等等)。
我不得不说我不是这个设计的忠实粉丝。 但是,你确定你的角色被召唤了吗? (也许一些system.outs会有帮助)。如果它从未被调用过,那么你最终会得到一个未初始化的牛。
此外,我不会尝试像这样自己实现XML解析器,因为您需要更加健壮以防止验证问题。
您可以使用SAX或DOM4J,甚至更好地使用Apache digester。
此外,如果我有一个模式,我将使用JaxB或其他代码生成器来加速XML接口代码的开发。代码生成器隐藏了直接使用SAX或DOM4J的许多复杂性。