Home > Back-end >  Removing selected child elements in a XML file C
Removing selected child elements in a XML file C

Time:08-16

I'm using tinyxml2. I have xml file with many elements on one node. My xml file:

<city>
    <school>
        <class>
            <boy name="Jose">
                <age>14</age>
            </boy>
            <boy name="Jim">
                <age>15</age>
            </boy>
            <boy name="Mike">
                <age>13</age>
            </boy>
            <boy name="Ben">
                <age>14</age>
            </boy>
            <boy name="Eddy">
                <age>14</age>
            </boy>
            <boy name="Jim">
                <age>16</age>
            </boy>
        </class>
    </school>
</city>

For example, I have to remove the last three boys. I wrote this, but it don't work.

void cropData(char *titlecity)
{
    tinyxml2::XMLNode *city = nullptr;
    tinyxml2::XMLNode *school = nullptr;
    tinyxml2::XMLNode *class = nullptr;
    tinyxml2::XMLError result;

    tinyxml2::XMLDocument doccity;
    doccity.LoadFile(titlecity);
    tinyxml2::XMLNode* root = doccity.FirstChild();
    if(root == nullptr)
        std::cout << "Cannot open file" << std::endl;

    city = doccity.FirstChildElement("city");
    assert(city);
    school = city->FirstChildElement("school");
    assert(school);
    class = school->FirstChildElement("class");
    assert(class);

    int i = 0;

    for (tinyxml2::XMLElement *boy = class->FirstChildElement("boy"); boy; boy = boy->NextSiblingElement("boy"))
    {
        if(i>3)
        {
            boy->Parent()->DeleteChild(boy);
        }
        i  ;
    }

    doccity.SaveFile("DeleteAttribute_demo_file.txt");
}

This code does not change file. I'm really sorry, if my english is bad.

CodePudding user response:

You have two errors in that code. One is a syntax error and the other is a logical error.

The syntax error is that you can't name a variable "class" because "class" is a reserved word in C .

The logical error is that your for loop is iterating over elements incrementing by using the element's NextSiblingElement getter function; however, once you delete the element it's next element is no longer valid.

See below:

namespace tx2 = tinyxml2;

void cropData(tx2::XMLDocument& doccity)
{
    tx2::XMLNode* city = nullptr;
    tx2::XMLNode* school = nullptr;
    tx2::XMLNode* class_ = nullptr;
    tx2::XMLError result;

    tinyxml2::XMLNode* root = doccity.FirstChild();
    if (root == nullptr)
        std::cout << "Cannot open file" << std::endl;

    city = doccity.FirstChildElement("city");
    school = city->FirstChildElement("school");
    class_ = school->FirstChildElement("class");

    int i = 0;
    auto* boy = class_->FirstChildElement("boy");
    while (boy != nullptr) {
        auto next = boy->NextSiblingElement("boy");
        if (i > 3) {
            boy->Parent()->DeleteChild(boy);
        }
        boy = next;
          i;
    }

    doccity.SaveFile("DeleteAttribute_demo_file.txt");
}

int main() {

    static const char* xml =
        "<?xml version=\"1.0\"?>"
        "<city>"
        "    <school>"
        "        <class>"
        "            <boy name=\"Jose\">"
        "                <age>14</age>"
        "            </boy>"
        "            <boy name=\"Jim\">"
        "                <age>15</age>"
        "            </boy>"
        "            <boy name=\"Mike\">"
        "                <age>13</age>"
        "            </boy>"
        "            <boy name=\"Ben\">"
        "                <age>14</age>"
        "            </boy>"
        "            <boy name=\"Eddy\">"
        "                <age>14</age>"
        "            </boy>"
        "            <boy name=\"Jim\">"
        "                <age>16</age>"
        "            </boy>"
        "        </class>"
        "    </school>"
        "</city>";

    tx2::XMLDocument doc;
    doc.Parse(xml);
    cropData(doc);
}
  • Related