C# 操作xml 在指定节点插入新节点,该如何操作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 操作xml 在指定节点插入新节点,该如何操作?相关的知识,希望对你有一定的参考价值。

C# 操作xml 在指定节点插入新节点,该如何操作?
<?xml version="1.0" standalone="yes"?><DocumentElement> <MM02 id="1"> <FNAM>BDC_SUBSCR</FNAM> <FVAL>SAPLMGD12033SUB7</FVAL> </MM02> <MM02 id="2"> <FNAM>BDC_SUBSCR</FNAM> <FVAL>SAPLMGD10001SUB9</FVAL> </MM02> <MM02 id="3"> <FNAM>BDC_SUBSCR</FNAM> <FVAL>SAPLMGD10001SUB10</FVAL> </MM02></DocumentElement>

实现后是:
<?xml version="1.0" standalone="yes"?><DocumentElement> <MM02 id="1"> <FNAM>BDC_SUBSCR</FNAM> <FVAL>SAPLMGD12033SUB7</FVAL> </MM02>
<MM02 id="1"> <FNAM>BDC_SUBSCR</FNAM> <FVAL>SAPLMGD12033SUB7</FVAL> </MM02> <MM02 id="2"> <FNAM>BDC_SUBSCR</FNAM> <FVAL>SAPLMGD10001SUB9</FVAL> </MM02> <MM02 id="3"> <FNAM>BDC_SUBSCR</FNAM> <FVAL>SAPLMGD10001SUB10</FVAL> </MM02></DocumentElement>

首先获取想要复制节点的值,然后添加。

 XElement rootNode = XElement.Load("test.xml");
            var result = from m in rootNode.Elements ("MM02")
                         where m.Attribute ("id").Value =="1"
                         select new 
                             
                                 id=m.Attribute ("id").Value ,
                                 fname = m.Element ("FNAM").Value ,
                                 fval = m.Element("FVAL").Value  
                             ;
            
            foreach (var s in result)
             
                XElement x = 
                    new XElement("MM02", new XAttribute("id",s.id ),
                    new XElement ("FNAM",s.fname ),
                    new XElement ("FVAL",s.fval)
                    );
                XElement node = rootNode.Element("MM02");
                rootNode.Element("MM02").AddAfterSelf(x);
                rootNode.Save("test.xml");
            

追问

你好,我用你的来实现,结果是多了一行及复制了两行,希望您在帮忙修改下,谢谢

追答

这个问题是这样的,在操作集合时不应该直接对集合进行修改,应该操作临时变量,修改后代码为

XElement rootNode = XElement.Load("test.xml");
            XElement temp = XElement.Load("test.xml");
            var result = from m in temp.Elements("MM02")
                         where m.Attribute ("id").Value =="1"
                         select new 
                             
                                 id=m.Attribute ("id").Value ,
                                 fname = m.Element ("FNAM").Value ,
                                 fval = m.Element("FVAL").Value  
                             ;

            foreach (var s in result)
            
               
                XElement x =
                    new XElement("MM02", new XAttribute("id", s.id),
                    new XElement("FNAM", s.fname),
                    new XElement("FVAL", s.fval)
                    );
                XElement node = rootNode.Element("MM02");
                rootNode.Element("MM02").AddAfterSelf(x);

            
            rootNode.Save("test.xml");

参考技术A 用Linq,去看看,很简单的

第五十四课 树中节点的插入操作

技术分享图片

 

问题:

新插入节点的位置如何指定?

非线性结构无法通过下标指定位置。

技术分享图片

 

 技术分享图片

 

插入操作代码流程:

技术分享图片

 

当前的树是一棵空树的话,新节点就当做空节点来插入。不是空树就查找新节点的父节点。

技术分享图片

 

 在GTree.h中添加插入操作:

  1 #ifndef GTREE_H
  2 #define GTREE_H
  3 
  4 #include "Tree.h"
  5 #include "GTreeNode.h"
  6 #include "Exception.h"
  7 
  8 namespace DTLib
  9 {
 10 
 11 template < typename T >
 12 class GTree : public Tree<T>
 13 {
 14 protected:
 15     GTreeNode<T>* find(GTreeNode<T>* node, const T& value) const
 16     {
 17         GTreeNode<T>* ret = NULL;
 18 
 19         if( node != NULL )
 20         {
 21             if( node->value == value )
 22             {
 23                 return node;
 24             }
 25             else
 26             {
 27                 for(node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
 28                 {
 29                     ret = find(node->child.current(), value);
 30                 }
 31             }
 32         }
 33 
 34         return ret;
 35     }
 36 
 37     GTreeNode<T>* find(GTreeNode<T>* node,  GTreeNode<T>* obj) const
 38     {
 39         GTreeNode<T>* ret = NULL;
 40 
 41         if( node == obj )
 42         {
 43             return node;
 44         }
 45         else
 46         {
 47             if( node != NULL )
 48             {
 49                 for( node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
 50                 {
 51                     ret = find(node->child.current(), obj);
 52                 }
 53             }
 54         }
 55 
 56         return ret;
 57     }
 58 public:
 59     bool insert(TreeNode<T>* node)
 60     {
 61         bool ret = true;
 62 
 63         if( node != NULL )
 64         {
 65             if( this->m_root == NULL ) //如果待插入节点的父节点为空,则这个节点将为根节点
 66             {
 67                 node->parent = NULL;
 68                 this->m_root = node;
 69             }
 70             else
 71             {
 72                 GTreeNode<T>* np = find(node->parent);
 73 
 74                 if( np != NULL )
 75                 {
 76                     GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
 77 
 78                     if( np->child.find(n) < 0 )
 79                     {
 80                         np->child.insert(n);
 81                     }
 82                 }
 83                 else
 84                 {
 85                     THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node...");
 86                 }
 87             }
 88         }
 89         else
 90         {
 91             THROW_EXCEPTION(InvalidParameterException, "Parameter node cannot be NULL ...");
 92         }
 93 
 94         return ret;
 95     }
 96 
 97     bool insert(const T& value, TreeNode<T>* parent)
 98     {
 99         bool ret = true;
100 
101         GTreeNode<T>* node = new GTreeNode<T>();
102 
103         if( node != NULL )
104         {
105             node->value = value;
106             node->parent = parent;
107 
108             insert(node);
109         }
110         else
111         {
112             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node ...");
113         }
114 
115         return ret;
116     }
117 
118     //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,这样有机会对里面的元素做进一步操作
119     SharedPointer< Tree<T> > remove(const T& value)
120     {
121         return NULL;
122     }
123 
124     SharedPointer< Tree<T> > remove(TreeNode<T>* node)
125     {
126         return NULL;
127     }
128 
129     GTreeNode<T>* find(const T& value) const  // 返回GTreeNode,赋值兼容性
130     {
131         return find(root(), value);
132     }
133 
134     GTreeNode<T>* find(TreeNode<T>* node) const
135     {
136         return find(root(), dynamic_cast<GTreeNode<T>*>(node));
137     }
138 
139     GTreeNode<T>* root() const
140     {
141         return dynamic_cast<GTreeNode<T>*>(this->m_root);
142     }
143 
144     int degree() const
145     {
146         return 0;
147     }
148     int count() const
149     {
150         return 0;
151     }
152 
153     int height() const
154     {
155         return 0;
156     }
157 
158     void clear()
159     {
160         this->m_root = NULL;
161     }
162 
163     ~GTree()
164     {
165         clear();
166     }
167 };
168 
169 }
170 
171 #endif // GTREE_H

 

测试程序如下:

 1 #include <iostream>
 2 #include "GTree.h"
 3 #include "GTreeNode.h"
 4 
 5 
 6 using namespace std;
 7 using namespace DTLib;
 8 
 9 
10 int main()
11 {
12     GTree<char> t;
13     GTreeNode<char>* node = NULL;
14 
15     t.insert(A, NULL);
16 
17     node = t.find(A);
18     t.insert(B, node);
19     t.insert(C, node);
20     t.insert(D, node);
21 
22     node = t.find(B);
23     t.insert(E, node);
24     t.insert(F, node);
25 
26     node = t.find(E);
27     t.insert(K, node);
28     t.insert(L, node);
29 
30     node = t.find(C);
31     t.insert(G, node);
32 
33     node = t.find(D);
34     t.insert(H, node);
35     t.insert(I, node);
36     t.insert(J, node);
37 
38     node = t.find(H);
39     t.insert(M, node);
40 
41     //用链表来验证我们的插入操作,从下至上遍历
42 
43     char* s = "KLFGMIJ";
44 
45     for( int i = 0; i < 7; i++ )
46     {
47         TreeNode<char>* node = t.find(s[i]);
48 
49         while( node != NULL )
50         {
51             cout << node->value << " ";
52 
53             node = node->parent;
54         }
55         cout << endl;
56     }
57 
58 
59     return 0;
60 }

结果如下:

技术分享图片

 

小结:

技术分享图片

 

技术分享图片

 

以上是关于C# 操作xml 在指定节点插入新节点,该如何操作?的主要内容,如果未能解决你的问题,请参考以下文章

第五十四课 树中节点的插入操作

如何搜索 xml 节点值,然后在 c# 中为该元素创建新属性

c#用XmlAttribute如何往xml文档里面节点写入属性?

C#在xml文件中指定节点插入节点和属性

节点操作

DOM节点:操作节点