1

我正在使用 Mini-XML 库来解析 XML 文件。

我几乎可以加载每个元素和属性,但是在加载长字符串时遇到了麻烦。

这是代码的相关部分:

//Load XML file into XmlO
    void load(wxString filenam){
        //First, convert wxString to std::string for safety (char* is transient), then to const char*
        std::string tmp_filenam = std::string(filenam.mb_str());
        const char* tmp_filenam2 = tmp_filenam.c_str();
        //Get pointer to file
        fp = fopen(tmp_filenam2,"r");
        //Load tree
        tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);

        //Close file (be nice!)
        fclose(fp);

        //Load <Systems> node
        Asset_elem = mxmlWalkNext(tree, tree, MXML_DESCEND_FIRST);

        //Start loading <asset> elements

        //Temporary Elements
        mxml_node_t *node; //Node to save
        mxml_node_t *subnode_pos; //Subnode for pos nodes
        mxml_node_t *subnode_GFX; //Subnode for GFX nodes
        mxml_node_t *subnode_pres; //Subnode for presence nodes
        mxml_node_t *subnode_gen; //Subnode for general nodes
        mxml_node_t *subnode_serv; //Subnode for services nodes
        mxml_node_t *subnode; //Subnode
        const char* name_tmp; //String for names of asset
        const char* tmp_str; //String for anything :P
        float x_pos; //X_pos Float
        float y_pos; //Y_pos Float
        const char* gfx_space;
        const char* gfx_ext;
        const char* pres_fac;
        float pres_val;
        int pres_range;
        const char* plan_class;
        int population;
        bool land;
        bool refuel;
        bool bar;
        bool missions;
        bool commodity;
        bool outfits;
        bool shipyard;
        const char* descrip;
        const char* bar_descrip;

        //Load first asset
        node = mxmlFindElement(Asset_elem, tree, "asset", NULL, NULL, MXML_DESCEND);
        //Start loading the rest of the ssys elements (but fail if first element is NULL)
        int i = 1;
        while (node != NULL){
            //Load name attrib
            name_tmp = mxmlElementGetAttr(node, "name");

            //Mark Branching nodes
            //Pos Element
            subnode_pos = mxmlFindElement(node, Asset_elem, "pos", NULL, NULL, MXML_DESCEND);
            //GFX Element
            subnode_GFX = mxmlFindElement(node, Asset_elem, "GFX", NULL, NULL, MXML_DESCEND);
            //Presence Element
            subnode_pres = mxmlFindElement(node, Asset_elem, "presence", NULL, NULL, MXML_DESCEND);
            //General Element
            subnode_gen = mxmlFindElement(node, Asset_elem, "general", NULL, NULL, MXML_DESCEND);
            //Services Sub-element
            subnode_serv = mxmlFindElement(subnode_gen, Asset_elem, "services", NULL, NULL, MXML_DESCEND);

/*********Loading routines that work********/

            //Get Descriptions

            const char * tmp_str;
            mxml_node_t *temp_sub_node;
            temp_sub_node = mxmlFindElement(subnode_gen, subnode_gen, "description", NULL, NULL, MXML_DESCEND);
            if(temp_sub_node != NULL){
                tmp_str = temp_sub_node->child->value.text.string;
            }
            else{
                tmp_str = NULL;
            }
        delete tmp_str;
        delete temp_sub_node;

这是我需要解析的一个元素:

<asset name="Ammu">
  <pos>
   <x>90.000000</x>
   <y>2490.000000</y>
  </pos>
  <GFX>
   <space>A00.png</space>
   <exterior>lava.png</exterior>
  </GFX>
  <presence>
   <faction>Empire</faction>
   <value>100.000000</value>
   <range>2</range>
  </presence>
  <general>
   <class>A</class>
   <population>60000</population>
   <services>
    <land/>
    <refuel/>
    <bar/>
    <missions/>
    <commodity/>
    <outfits/>
   </services>
   <commodities>
    <commodity>Food</commodity>
    <commodity>Ore</commodity>
    <commodity>Industrial Goods</commodity>
   </commodities>
   <description>Ammu is a generally calm planet, once one is accustomed to the constant rumbling of the lava flows. Lava eruptions are often felt in the subterranean spaceport, but the way it doesn't seem to phase the locals reassures you.</description>
   <bar>The Ammu Spaceport Bar, known as "The Heatsink" due to its frigid temperatures, in contrast to the rest of the station. While primarily known for their temperature, that's not to say they can't whip up a mean Pan-Galactic Gargle Blaster.</bar>
  </general>
  <tech>
   <item>Basic Outfits 1</item>
  </tech>
 </asset>

我只从描述标签中得到第一个单词。

为什么?

编辑 1:我尝试切换到 std::string,但 MiniXML 库返回一个 const char*,它显然不能容纳这么长的字符串。

有什么建议么?

编辑 2:我将回调更改为 OPAQUE,以便它忽略空格,但现在它只返回 NULL。

编辑 3:我现在更改了获取 value.opaque 而不是 value.text.string 的方法。这使得“description”标签工作得很好,但是当我尝试将它加载到 const char* 时,“bar”标签仍然崩溃。我尝试从 xml 文件中删除引号等,以查看是否是导致它的原因,但它没有帮助。

编辑 4:我什至删除了除一个“资产”对象之外的所有对象,然后删除了它的“栏”元素,但它仍然崩溃。这绝对是奇怪的!

编辑 5:好的,我隔离了问题代码:

tmp_str = temp_sub_node->child->value.opaque;

但是,我已将此集成到一个方法中,与我用于描述元素(直接位于它之前)的方法相同,并且效果很好。怎么了?

编辑 6:奇怪的是,当我将搜索字符串更改为“bar”时,它会优雅地失败(即返回 NULL)。只有当我将其更改为“bar”(我需要的元素)时,它才会崩溃。这是保留关键字还是mini xml不喜欢的东西?!

编辑 7:终于!弄清楚了。我将 MXML_DESCEND 更改为 MXML_DESCEND_FIRST,它工作正常。哇!!!!终于解脱了。多谢你们!

4

2 回答 2

2

您需要替换: tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);

经过:

树 = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);

那是你试过的吗?

我认为您还需要阅读价值,例如

tmp_str = temp_sub_node->child->value.opaque;

于 2010-10-22T21:09:10.530 回答
0

如果您使用的是 C++,那么可以使用“字符串”STL 类来处理字符串。它可以加载任意数量的字符,直到内存限制。

于 2010-10-20T04:58:02.520 回答