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);
}