Обработка ошибок для парсинга 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;

Я не раздражаю и пыхчу по нему, но если бы кто-либо может думать о более чистом способе выполнить это, это ценилось бы.

P.S. Исключения не опция.

Править:

Что-то вроде этого было бы предпочтительно?

if ( !path ) {
  // Handle error, return false
}
// Continue

Это устраняет код стрелки, но код стрелки отчасти помещает всю регистрацию ошибок на одном месте.

1
задан random 3 July 2010 в 18:59
поделиться

3 ответа

Использование возвращаемых значений в качестве кодов ошибок просто приводит к такому коду, его нельзя значительно улучшить. Немного более чистый способ - использовать goto , чтобы сгруппировать всю обработку ошибок в один блок и уменьшить вложение блоков.

Однако это не решает реальной проблемы, заключающейся в использовании возвращаемых значений в качестве кодов ошибок. В C нет альтернативы, но в C ++ есть исключения, и их следует использовать. Если они не подходят, вы застряли с тем, что у вас есть.

2
ответ дан 2 September 2019 в 23:19
поделиться

Для этого можно создать макрос, который инкапсулирует if (!var) { ... return false; } и отчет об ошибках.

Однако я не вижу, как это можно улучшить; это просто то, что есть. C'est la vie. C'est le code...

0
ответ дан 2 September 2019 в 23:19
поделиться

Я не фыркаю над этим, но если кто может придумать уборщика способ добиться этого было бы оценен.

Я заменил вложенные ifs операторами return в случае ошибки (это заставляет код «течь вниз» вместо того, чтобы идти «в форме стрелки». Я также заменил ваши do loopps на циклы for (чтобы я мог лучше понять это).

Это то, что вы хотели?

const TiXmlElement *objectType = dataRoot->FirstChildElement( "game_object" );
if ( !objectType ) {
    LogErr( "No game_object specified in <game_objects>. Thus, not necessary." );
    return false;
}

for(; objectType != 0; objectType = objectType->NextSiblingElement( "game_object" )) {
    const char *path = objectType->Attribute( "path" );
    if ( !path ) {
        LogErr( "No path specified for GameObject in state file." );
        return false;
    }

    const TiXmlElement *instance = objectType->FirstChildElement( "instance" ); 
    if ( !instance ) {
        LogErr( "No instances specified for GameObject in state file." );
        return false;
    }

    for(; instance != 0; instance = instance->NextSiblingElement( "instance" )) {
        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;
        }
    }
}
return true;
0
ответ дан 2 September 2019 в 23:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: