0

libxml2 を使用して、作成中のプログラムの構成情報を含む XML ファイルを c で作成および読み取ります。プログラムは独自の構成ファイルを作成します (または、別のプログラムが構成ファイルを送信し、構成ファイルに基づいてプログラムを実行するように要求します)。そのため、XML 構成ファイルは、人間にとって非常に読みやすいものである必要はありません。

これらの構成ファイルには多くの値が含まれており、非常に長いです。そのため、現在、XML ファイルを作成する関数と、XML ファイルを読み取る関数があります。ただし、書き込み XML 関数を変更するときはいつでも、読み取り XML 関数も変更する必要があります。したがって、実際のコードの重複はありませんが、非常に近いもの (つまり、BAD)があり、構成ファイルが非常に長いため、すべてが同じものを読み書きしていることを確認するのはかなり面倒です。

これが現在のセットアップです。

struct config_data
{
    // category one
    int X
    int Y

    // category two
    int Z
    int A
}


int makeXMLsheet(char* fileout)
{
    xmlDocPtr doc = NULL;       /* document pointer */
    xmlNodePtr root_node = NULL; /* node pointers */   

    LIBXML_TEST_VERSION;

    doc = xmlNewDoc((xmlChar*) "1.0");
    root_node = xmlNewNode(NULL, BAD_CAST "configuration_file");
    xmlDocSetRootElement(doc, root_node);    

    // catogory one
    xmlNodePtr category_one =  xmlNewChild(root_node, NULL, BAD_CAST "category_one", NULL);    

    xmlNewChild(category_one, NULL, BAD_CAST "x", BAD_CAST "12345");
    xmlNewChild(category_one, NULL, BAD_CAST "y", BAD_CAST "1");

     // catogory two
    xmlNodePtr category_two =  xmlNewChild(root_node, NULL, BAD_CAST "category_two", NULL);    

    xmlNewChild(category_two, NULL, BAD_CAST "Z", BAD_CAST "12345");
    xmlNewChild(category_two, NULL, BAD_CAST "A", BAD_CAST "1");

    xmlSaveFormatFileEnc(fileout, doc, "UTF-8", 1);
    xmlFreeDoc(doc);
    xmlCleanupParser();

    return 0;
}


int readXMLsheet(char* filename,struct *config_data)
 {
     xmlDocPtr doc = getdoc(filename);

     config_data->X = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_one/X"); 
     config_data->Y = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_one/Y");
     config_data->Z = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_two/Z");
     config_data->A = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_two/a");

    xmlFreeDoc(doc);
     return 0;
 }

どこ

 int getIntegerFromXML(int defaultValue, xmlDocPtr doc, xmlChar *xpath)

その名前が示すように、xpath の場所を持つ開かれた XML ドキュメントから整数を取得し、失敗した場合は、プログラムがクラッシュしたり燃えたりしないようにデフォルト値を入力します。

そこで、読み取り機能と書き込み機能を 1 つにまとめる方法を試してみたいと思います。私のサンプル struct config-data は、構成構造体に実際にある値の数に比べて小さいので、それらを組み合わせることで、すべてを簡単に追跡できます。

そこで、こんなことを考えていました。

int openXMLvalue(X, Y, Z, readOrWrite, defaultValue, value);

親ノードはどこにありX, Y, Zますが、3 つより多い場合も少ない場合もあります。

これを行う方法についてのアイデアはありますか?たぶん、ある種の配列を作成しますか?

4

2 に答える 2

0

一般的な構成構造を設定 (またはシリアル化) する一般的な読み取りおよび書き込み関数を作成します。

簡単なケースは、get/set メソッドを使用してメモリ内にキー/値構造を作成することです。一般的な writeToXml 関数は、値を含むキー名を持つ要素を作成するだけです。

保証されている場合は、代わりに階層ツリー構造を使用し、必要な構成値が存在し、有効であることを確認するために、構成ファイルを読み取るときにいくつかの検証規則を追加することもできます (単純なものは、検証に XML スキーマを使用することです)。

構成値を追加、変更、または削除するには、次の手順のみが必要です (読み取り関数も書き込み関数も更新を必要としないことに注意してください)。

  • 構成ファイルの新しい形式を決定する
  • 既存の構成ファイルを更新する
  • 構成値を使用してアプリケーション内の任意の場所を更新します
  • 必要に応じて検証ルールを更新します
于 2012-04-30T18:28:31.617 に答える
0

構成ファイルのサイズが大きいため、sqlite の使用に切り替えました。次に、データベースを読み取って xml シートを作成する関数を作成し、xml シートを読み取ってデータベースにデータを入力する関数を作成し、データベースを印刷して C 構造体に入力する関数を作成しました。これで生活がかなり楽になると思います。

于 2012-06-04T20:12:40.887 に答える