Below I have a sample of my XML file, I want to delete a specific node in each header. How do i do it. for example in header<HEADER> i want to delete the node <ADDRESS>, not just its attribute but the whole node. in <HEADER1> I need to delete the attribute <UMG_VAR Name="ABC" Value=1></UMG_var>, here Name attribute is unique.
<MAIN>
<HEADER>
<TITLE>ppc_ph_pios</TITLE>
<AUTOR>DNL</AUTOR>
<AGE>age</AGE>
<SEX>Male</SEX>
<PLACE>Earth</PLACE>
<ADDRESS>abc</ADDRESS>
</HEADER>
<HEADER1>
<UMG_VAR Name="RED" Value="3"></UMG_VAR>
<UMG_VAR Name="ABC2" Value="2"></UMG_VAR>
<UMG_VAR Name="ABC" Value="1"></UMG_VAR>
</HEADER2>
</MAIN>
QDomDocument doc;
doc.setContent(oldXml);
QDomNodeList nodes = doc.elementsByTagName("element");
for (int i = 0; i < nodes.count(); ++i)
{
QDomNode node = nodes.at(i);
QDomElement child = node.firstChildElement("child");
if (!child.isNull() && child.attribute("id") == "0")
{
node.removeChild(child);
}
}
QString newXml = doc.toString();
Related
<Node>
<A>
<B id = "it_DEN"></B>
</A>
<A>
<B id = "en_KEN"></B>
</A>
<A>
<B id = "it_BEN"></B>
</A>
</Node>
How can I remove child node of <A></A> that has child node <B></B> which has attribute id not starts with it using PugiXML.
The result would be as below:
<Node>
<A>
<B id = "it_DEN"></B>
</A>
<A>
<B id = "it_BEN"></B>
</A>
</Node>
This is slightly tricky if you want to remove nodes while iterating (to keep the code single-pass). Here's one way to do it:
bool should_remove(pugi::xml_node node)
{
const char* id = node.child("B").attribute("id").value();
return strncmp(id, "it_", 3) != 0;
}
for (pugi::xml_node child = doc.child("Node").first_child(); child; )
{
pugi::xml_node next = child.next_sibling();
if (should_remove(child))
child.parent().remove_child(child);
child = next;
}
Alternatively you can just use XPath and remove the results:
pugi::xpath_node_set ns = doc.select_nodes("/Node/A[B[not(starts-with(#id, 'it_'))]]");
for (auto& n: ns)
n.node().parent().remove_child(n.node());
Another way is to increment the iterator before removing the child. To remove an attribute while iterating.
for(pugi::xml_attribute_iterator it = node.attributes_begin(); it != node.attributes_end();){
pugi::xml_attribute attr = *it++;
if(should_remove(attr)){
node.remove_attribute(attr);
}
}
Below i have show a normal XML file:
<Header>
<Sub Name="" Value="" /Sub>
<Sub Name="" value="" /Sub>
.
.
.
.
</Header>
I read the above mentioned XML like this:
QStringList Name;
QStringList value;
QXmlGet xmlget;
xmlget.load(Sample.xml);
xmlget.findAndDescend("Header");
while(xmlget.findNext("Sub")
{
Name.append(xmlget.getAttributeString("Name". "Unknown"));
value.append(xmlget.getAttributeString("value". "Unknown"));
}
xmlget.save(Sample.xml);
But the xml i have right now is bit complicated.
XML:
<Header>
<Sub Name= "" Value = ""><Sub1 Name = ""></Sub1></Sub>
<Sub Name= "" value = "" /Sub>
<Sub Name= "" Value = ""><Sub1 Name = ""></Sub1></Sub>
.
.
.
</Header>
Any suggestions how do I read the <Sub1>
Something like this one (Tested! It works!)
QStringList Name;
QStringList value;
QXmlGet xmlget;
xmlget.load("Sample.xml");
xmlget.findAndDescend("Header");
QXmlPut xmlPut(xmlget); // init reference from the variable - xmlget
while(xmlget.findNext("Sub")) {
Name.append(xmlget.getAttributeString("Name", "Unknown"));
value.append(xmlget.getAttributeString("Value", "Unknown"));
xmlget.descend(); // now Sub is the parent element
if( xmlPut.hasChildren() ) {
while(xmlget.findNext("Sub1") { // finding relatively the parent - Sub
xmlPut.goTo(xmlget.element());
xmlPut.setAttributeString("Name", "NAME1");
xmlPut.setAttributeString("Value", "VALUE1");
}
} else {
xmlPut.putInt("IntTag", "IntValue"); // We create the child node (IntTag) of the parent (Sub)
xmlPut.setAttributeString("AttrName", "AttrValue"); // and add some attributes to it
}
xmlget.rise();
}
xmlPut.save("Sample.xml"); // Any file name to save the xml data
docs
i have xml file like this
<root>
<element>
<child id = "0"> Some Text </child> <-- Target To Delete
</element>
<element>
<child id = "1"> Some Text </child>
</element>
</root>
how can i delete child element of id "0" ? using Qt library.
QDomDocument doc;
doc.setContent(oldXml);
QDomNodeList nodes = doc.elementsByTagName("element");
for (int i = 0; i < nodes.count(); ++i)
{
QDomNode node = nodes.at(i);
QDomElement child = node.firstChildElement("child");
if (!child.isNull() && child.attribute("id") == "0")
{
node.removeChild(child);
}
}
QString newXml = doc.toString();
How do I remove a child with a specific attribute? I´m using c++/libxml2. My attempt so far (in the example I want to remove child node with id="2"):
Given XML:
<p>
<parent> <--- current context
<child id="1" />
<child id="2" />
<child id="3" />
</parent>
</p>
xmlNodePtr p = (parent node)// Parent node, in my example "current context"
xmlChar* attribute = (xmlChar*)"id";
xmlChar* attribute_value = (xmlChar*)"2";
xmlChar* xml_str;
for(p=p->children; p!=NULL; p=p->next){
xml_str = xmlGetProp(p, attribute);
if(xml_str == attribute_value){
// Remove this node
}
}
xmlFree(xml_str);
Call xmlUnlinkNode to remove a node. Call xmlFreeNode to free it afterward, if you want:
for (p = p->children; p; ) {
// Use xmlStrEqual instead of operator== to avoid comparing literal addresses
if (xmlStrEqual(xml_str, attribute_value)) {
xmlNodePtr node = p;
p = p->next;
xmlUnlinkNode(node);
xmlFreeNode(node);
} else {
p = p->next;
}
}
Haven't used this library in a while, but check out this method. Note that per the description, you need to call xmlUnlinkNode first.
Why is this loop only running once?
noteDatabaseItem just takes a node and fills in the data. the xml has 3 notes in it.
XML:
<?xml version="1.0" encoding="utf-8"?>
<noteCollection>
<note name="Test Note 1">This is test note 1 content!</note>
<note name="Test Note 2">This is test note 2 content!</note>
<note name="Test Note 3">This is test note 3 content!</note>
</noteCollection>
C++:
std::vector<notekeeper::noteDatabaseItem> noteList;
TiXmlElement* noteCollection = xmlDoc->FirstChildElement("noteCollection");
TiXmlElement* node = noteCollection->FirstChildElement("note");
int itemCount = 0;
while (node != NULL) {
itemCount++;
noteList.resize(itemCount);
noteList.push_back(noteDatabaseItem(node));
node = noteCollection->NextSiblingElement("note");
}
Shouldn't it be node = node->NextSiblingElement("note")?
noteCollection has only children, not siblings, right?
You're getting the wrong element in your loop. Try this:
while (node != NULL) {
itemCount++;
noteList.push_back(noteDatabaseItem(node));
node = node->NextSiblingElement("note");
}
The next sibling of the current node is the one you want. You were trying to get the next sibling of the parent node.
node = noteCollection->NextSiblingElement("note");
is meant to be
node = node->NextSiblingElement("note");
Stupid mistake. Sibling not Child.