现有A、B两个xml文件,想要按照一个顺序要求把B中的节点拷贝到A中,之前用insertafterchild函数,总会在afterThis参数判断时不通过afterThis->_parent != this,百思不得其解。后改变思路并改变函数,使用InsertEndChild函数,顺利实现。
思路是,每次运行先将A清空,再从B中按索引条件找到需要的节点复制给A。这样不管顺序要求怎么变,函数都可以实现相应的功能。
下面上代码:
// TODO: 在此添加命令处理程序代码
UpdateData(true);//从界面更新顺序要求
tinyxml2::XMLDocument docXmlB;//B.xml
XMLError errXml = docXmlB.LoadFile("B.xml");
if (XML_SUCCESS != errXml)
{
return;
}
tinyxml2::XMLNode* elmtRootB = docXmlB.FirstChild();
const tinyxml2::XMLNode* node = elmtRootB->FirstChild();
bool findB = false;
int i = 0;//遍历list
bool find = false;//是否找到节点
CString instructname = "";//顺序要求,我的是在list列表中得到的
tinyxml2::XMLNode* elmtRootA = docXmlA.FirstChild();
//elmtnode是p_element的节点形式
tinyxml2::XMLNode* vernier = NULL;//游标
tinyxml2::XMLNode* elmtnode = elmtRootA->FirstChild();
if (elmtnode)//A为空直接往里添加节点,不空则清空
{
while (elmtnode->NextSibling() != NULL)//循环找到A的最后一个子节点
{
elmtnode = elmtnode->NextSibling();
}
for (; elmtnode;)//删除所有子节点
{
vernier = elmtnode;
elmtnode = elmtnode->PreviousSibling();
elmtRoot->DeleteChild(vernier);
}
}
for (; m_testlist.GetItemText(i, 0) != "";)
{
find = false;
findcommand = false;
instructname = m_testlist.GetItemText(i, 0);//顺序要求
// 新建节点,在B中找到instructname的节点
for (node = elmtRootB->FirstChild(); node; node = node->NextSibling())
{
const XMLElement* Bnode = node->ToElement();
const XMLAttribute *Attr = Bnode->FirstAttribute();
while (Attr)
{
if ((CString)(Attr->Name()) == "name" && (CString)(Attr->Value()) == instructname)
{
//找到节点
findB = true;
}
Attr = Attr->Next();
}
if (findB)
break;
}
tinyxml2::XMLNode* copy = node->DeepClone(&docXmlA);
elmtRootA->InsertEndChild(copy);
i++;
}
docXmlA.SaveFile(docXmlApath);
容易出问题是在最后几行,
tinyxml2::XMLNode* copy = node->DeepClone(&docXmlA);
node要判断是不是为NULL;DeepClone的参数是A的文档对象引用;
elmtRootA->InsertEndChild(copy); 用根节点的insertendchild函数,不是用docXmlA。