xml解析错误处理
我使用tinyxml 来解析xml 文件,并且我发现这里的错误处理适合箭头代码。我们的错误处理只是向文件报告一条消息。
这是一个例子:
const TiXmlElement *objectType = dataRoot->FirstChildElement( "game_object" );
if ( objectType ) {
do {
const char *path = objectType->Attribute( "path" );
if ( path ) {
const TiXmlElement *instance = objectType->FirstChildElement( "instance" );
if ( instance ) {
do {
int x, y = 0;
instance->QueryIntAttribute( "x", &x );
instance->QueryIntAttribute( "y", &y );
if ( x >= 0 && y >= 0 ) {
AddGameObject( new GameObject( path, x, y ));
} else {
LogErr( "Tile location negative for GameObject in state file." );
return false;
}
} while ( instance = instance->NextSiblingElement( "instance" ));
} else {
LogErr( "No instances specified for GameObject in state file." );
return false;
}
} else {
LogErr( "No path specified for GameObject in state file." );
return false;
}
} while ( objectType = objectType->NextSiblingElement( "game_object" ));
} else {
LogErr( "No game_object specified in <game_objects>. Thus, not necessary." );
return false;
}
return true;
我并没有对此气喘吁吁,但如果有人能想出一种更干净的方法来实现这一点,我将不胜感激。
PS 例外不是一个选项。
编辑:
这样的事情会更好吗?
if ( !path ) {
// Handle error, return false
}
// Continue
这消除了箭头代码,但箭头代码有点将所有错误记录放在一处。
I'm using tinyxml to parse xml files, and I've found that error handling here lends itself to arrow code. Our error handling is simply reporting a message to a file.
Here is an example:
const TiXmlElement *objectType = dataRoot->FirstChildElement( "game_object" );
if ( objectType ) {
do {
const char *path = objectType->Attribute( "path" );
if ( path ) {
const TiXmlElement *instance = objectType->FirstChildElement( "instance" );
if ( instance ) {
do {
int x, y = 0;
instance->QueryIntAttribute( "x", &x );
instance->QueryIntAttribute( "y", &y );
if ( x >= 0 && y >= 0 ) {
AddGameObject( new GameObject( path, x, y ));
} else {
LogErr( "Tile location negative for GameObject in state file." );
return false;
}
} while ( instance = instance->NextSiblingElement( "instance" ));
} else {
LogErr( "No instances specified for GameObject in state file." );
return false;
}
} else {
LogErr( "No path specified for GameObject in state file." );
return false;
}
} while ( objectType = objectType->NextSiblingElement( "game_object" ));
} else {
LogErr( "No game_object specified in <game_objects>. Thus, not necessary." );
return false;
}
return true;
I'm not huffing and puffing over it, but if anyone can think of a cleaner way to accomplish this it would be appreciated.
P.S. Exceptions not an option.
Edit:
Would something like this be preferable?
if ( !path ) {
// Handle error, return false
}
// Continue
This eliminates the arrow code, but the arrow code kind of puts all of the error logging on one place.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用返回值作为错误代码只会导致这样的代码,它无法改进太多。一种稍微简洁的方法是使用 goto 将所有错误处理分组到单个块中并减少块的嵌套。
然而,这并没有解决实际问题,即使用返回值作为错误代码。在 C 中,没有其他选择,但在 C++ 中,异常是可用的并且应该使用。如果它们不是一个选择,你就会被现有的东西所困。
Using return values as error codes just leads to such code, it can't be improved much. A slightly cleaner way would use
goto
to group all error handling into a single block and to decrease the nesting of blocks.This does however not solve the actual problem, which is using return values as error codes. In C, there is no alternative, but in C++ exceptions are available and should be used. If they are not an option, you're are stuck with what you have.
您可以为此创建一个宏,它封装了 if (!var) { .. return false; } 和错误报告。
然而,我不认为这可以得到多大改善;事情就是这样。 这就是生活。这是代码...
You could create a macro for that, which encapsulates the
if (!var) { .. return false; }
and error reporting.However, I do not see how this can be improved all that much; its just the way it is. C'est la vie. C'est le code...
我已经将嵌套的 if 替换为错误时的 return 语句(这使得代码“向下流动”而不是“箭头形状”。我还用 for 循环替换了 do 循环(这样我可以更好地理解它)。
这是什么?你想要吗?
I have replaced the nested ifs with return statements on error (this makes the code "flow down" instead of going "arrow shaped". I have also replaced your do loopps with for loops (so I could understand it better).
Is this what you wanted?
我知道有点晚了,但我知道 QueryIntAttribute 返回一个值,可用于错误处理,以防您也希望将其用于属性。
I know it is a little late, but I know that QueryIntAttribute returns a value which can be used for error handling in case you want this for your attributes too.