有段时间没有去编写XML的相关代码了,除了上次写了删除XML节点外,今天遇到个XML节点的插入问题。由于XML树的物理特性,插入节点务必会动整棵树的物理结构。当我要决定这样做的时候,同事和网友都不建议我这样做,但为达到老总的要求还是不得不想办法来实现,经过一天多的努力还是想出了笨拙的办法来,但这程序代码中本省就存在缺陷,因为需要循环执行,对于一个小型的XML文件处理起来,自然游刃有余,但文件一旦变大,而且插入得位置靠前的话,就得对整个叶子节点都进行改动,因此时间复杂度比较高。
废话少说,进入正题:
用的到基类还是CCEXML
自己的类class CMYXML : public CCEXML
CMYXML myeditxml;
主程序中调用到XML得地方://XML节点插入口
void CDataInput::OnBTNSave()
{
// TODO: Add your control notification handler code here
int m_insert_i;
CString s;
POSITION pos=m_view_list.GetFirstSelectedItemPosition(); //从列表中获取当前选中信息所在的XML节点信息索引号(因为所读取的列表是跟XML文件中的索引号是一一对应的)。
int i=(int)pos-1;
m_edit_name.GetWindowText(s); //获取重新移动到得索引号
m_insert_i=_wtoi(s); //CString转换为int型
if (m_insert_i<i) //如果节点往前面插入
{
for (int j=i;j>m_insert_i;j--) //插入节点处以下节点循环下移
{
ReplaceRadioInformation(j); //将索引号靠前的信息移动后面一个节点信息上
}
ReEditNode(m_insert_i); //将选取的节点信息插入到插入节点位置上
}
else if (m_insert_i==i) //如果原节点不懂,当做修改处理
{
ReEditNode(i); //修改当前节点的信息
}
else //如果节点往后面插入
{
for (int k=i;k<m_insert_i;k++) //插入节点处以下节点循环上移
{
ReplaceUpInformation(k); //将索引号靠后的信息移动前一个节点信息上
}
ReEditNode(m_insert_i); //将选取的节点信息插入到插入节点位置上
}
myeditxml.SaveXML(L"//SDMMC//EVC测试程序//CND_620F收音机应用程序//Radio.xml");//保存XML文件
m_view_list.DeleteAllItems();//清空原先列表
myeditxml.LoadXML(L"//SDMMC//EVC测试程序//CND_620F收音机应用程序//Radio.xml");
ReadlistNode(L"/CND620F/Radio/FM");//重新刷新列表
}
下移节点函数:
void CDataInput::ReplaceRadioInformation(int i)
{
IXMLDOMNodeList *NodeList = NULL;
IXMLDOMNode *iNode = NULL;
IXMLDOMNode *iNodeNext = NULL;
IXMLDOMNode *pchild = NULL;
IXMLDOMNode *pchildNext = NULL;
IXMLDOMNode *Sibling = NULL;
IXMLDOMNode *SiblingNext = NULL;
BSTR bstr1,bstr2;
NodeList = myeditxml.FindNodeList(L"/CND620F/Radio/FM");
long count=0;
NodeList->get_length(&count);
NodeList->get_item(i-1,&iNode);
NodeList->get_item(i,&iNodeNext);
//对第一个节点进行移花接木
iNode->get_firstChild(&pchild);
iNodeNext->get_firstChild(&pchildNext);
pchild->get_text(&bstr1);
pchildNext->put_text(bstr1);
//获取下一个叶子节点,进行移花接木
pchild->get_nextSibling(&Sibling);
pchildNext->get_nextSibling(&SiblingNext);
pchild = Sibling;
pchildNext = SiblingNext;
pchild->get_text(&bstr2);
pchildNext->put_text(bstr2);
}
修改当前节点的函数
void CDataInput::ReEditNode(int i)
{
IXMLDOMNodeList *NodeList = NULL;
IXMLDOMNode *iNode = NULL;
IXMLDOMNode *pchild = NULL;
IXMLDOMNode *Sibling = NULL;
BSTR bstr1,bstr2;
CString str1,str2;
m_edit_freq.GetWindowText(str2);
m_edit_number.GetWindowText(str1);
//edit_name.GetWindowText(s);
NodeList = myeditxml.FindNodeList(L"/CND620F/Radio/FM");
long count=0;
NodeList->get_length(&count);
NodeList->get_item(i,&iNode);
//对第一个节点进行手术
iNode->get_firstChild(&pchild);
bstr1=str1.AllocSysString();
pchild->put_text(bstr1);
//获取下一个叶子节点进行手术
pchild->get_nextSibling(&Sibling);
pchild = Sibling;
bstr2=str2.AllocSysString();
pchild->put_text(bstr2);
}
上移节点函数
void CDataInput::ReplaceUpInformation(int i)
{
IXMLDOMNodeList *NodeList = NULL;
IXMLDOMNode *iNode = NULL;
IXMLDOMNode *iNodeNext = NULL;
IXMLDOMNode *pchild = NULL;
IXMLDOMNode *pchildNext = NULL;
IXMLDOMNode *Sibling = NULL;
IXMLDOMNode *SiblingNext = NULL;
BSTR bstr1,bstr2;
NodeList = myeditxml.FindNodeList(L"/CND620F/Radio/FM");
long count=0;
NodeList->get_length(&count);
NodeList->get_item(i+1,&iNode);
NodeList->get_item(i,&iNodeNext);
//对第一个节点进行移花接木
iNode->get_firstChild(&pchild);
iNodeNext->get_firstChild(&pchildNext);
pchild->get_text(&bstr1);
pchildNext->put_text(bstr1);
//获取下一个叶子节点,进行移花接木
pchild->get_nextSibling(&Sibling);
pchildNext->get_nextSibling(&SiblingNext);
pchild = Sibling;
pchildNext = SiblingNext;
pchild->get_text(&bstr2);
pchildNext->put_text(bstr2);
}