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