首页 新闻 会员 周边 捐助

C#操作XML,如何获取指定节点值?

-1
悬赏园豆:100 [已解决问题] 解决于 2012-05-11 10:16
1 <?xml version="1.0" encoding="utf-8" ?>
2 <test>
3 abc
4 <!--注释-->
5 <test2>
6 abc
7 <!--注释-->
8 </test2>
9 </test>

如何修改test节点下的第一个abc值?


test节点下的InnerText是
abc
abc

test节点下的InnerXml是

 abc
<!--注释-->
<test2>
abc
<!--注释-->
</test2>

 

看起来无法直接修改InnerText来实现,请问如何正确修改呢?

遍历获取各个节点是这样





自己解决,感谢大家的关注和指点。随便给点分了


我用的treelist控件控件进行各个节点的显示,treelist的第一列存xmlnode.name,第二列是
xmlnode.value,tag是node。所以修改后,可以遍历这些节点值或者注释的父节点下的所有子节点,= tag的就是这个修改的节点,设置其value后保存即可
其中
xmlDoc是一个全局变量,打开时给他赋值,以后不重复打开了。如果重复打开同一文件判断
(xnl == node)时很可能不相等


/// <summary>
        /// 修改 <a>text</a> 里的text,防止内部有注释或者更多注记。此函数可能仍不好用,仍需改进
        /// </summary>
        /// <param name="xmlpath">The xmlpath.</param>
        /// <param name="node">The node.</param>
        /// <param name="value">The value.</param>
        private void UpdateInnerXml(string xmlpath, string nodename, string value, XmlNode node)
        {
            try
            {
                XmlNode xn = xmlDoc.SelectSingleNode(nodename);

                XmlNode xnl = null;
                bool exist = false;
                ////理论上这里可以找到一个子节点Name == "#text"且=treelist node的tag,如果没找到再考虑截位
                for (int i = 0; i < xn.ChildNodes.Count; i++)
                {
                    xnl = xn.ChildNodes[i];
                    if (xnl == node)
                    {
                        exist = true;
                        break;
                    }
                }

                if ((xnl != null) && exist)
                {
                    xnl.Value = value; 
                    node.Value = value; 
                }
                else
                {
                    XmlElement xe = (XmlElement)xn;
                    ////截取xe.InnerXml中xe.InnerText部分替换为修改内容,有与xe.InnerText相同的其他地方或稍微复杂的比如前面的例子就无法处理了
                    xe.InnerXml = xe.InnerXml.Substring(0, xe.InnerXml.IndexOf(xe.InnerText)) + value + xe.InnerXml.Substring(xe.InnerXml.IndexOf(xe.InnerText) + xe.InnerText.Length);
                }
                xmlDoc.Save(xmlpath);
            }
            catch
            {
            }
        }

 







jhlong的主页 jhlong | 初学一级 | 园豆:21
提问于:2012-05-10 17:04
< >
分享
最佳答案
0

你直接用InnerText是不可能达到你的目的的。

对于内含子节点的节点,不应该直接放置文本内容。如果有需要,你可以增加一个特殊的子节点,比如Content。因为按照你这样的,操作不是很保险。

对于你的这个问题,也不是完全不可以解决,只是不安全。

你可以对你的Test节点枚举其所有的直接子节点,你会发现其中有一个子节点就是这个节点的文本内容的节点,具体这个节点的识别我忘记了(呵呵,好久没这样调试过了),你可以调试跟踪下,然后有了个定性后,再确定方法来处理。

收获园豆:60
无之无 | 大侠五级 |园豆:5095 | 2012-05-10 17:18

上传了个节点结构图片

 

主要是写个操作xml的工具,虽然不安全,我也不喜欢这样组织xml,但是这种情况还是要考虑下

其他情况下的编辑还是很好处理的

jhlong | 园豆:21 (初学一级) | 2012-05-10 17:24
其他回答(3)
0

直接操作字符串可以吧!?<test>节点后<test2>节点前

收获园豆:10
heqichang | 园豆:275 (菜鸟二级) | 2012-05-10 17:11

操作字符串当然可以,但是要知道xml里的string字符串

 

这里我需要一个通用的方法,xml里的string字符串是多样的不一样的,可能有attribute,注释等,最好是c#利用xml的那个类来实现?

支持(0) 反对(0) jhlong | 园豆:21 (初学一级) | 2012-05-10 17:14

@jhlong: C#里有一套操作方法,Attribute也有专门的方法的,你可以看下帮助文档。

另外,假如你使用的是.NET 3.0或以上版本,类库里已经有XElement,建议用这个,性能、查询会更方便点。

至于AZ235的方案,这个是不保险的。你可以跟踪看,#Text,是什么节点,能否通过特别的识别检索出来。

支持(0) 反对(0) 无之无 | 园豆:5095 (大侠五级) | 2012-05-10 17:50

@jhlong: 或者换种方式组织你的xml!?

比如这样!?

<?xml version="1.0" encoding="utf-8" ?>
<root>
<nodes>
<node id="1" value="01">
<node id="2" value="02" />
</node>
</nodes>

<values>
<value id="01" text="test1" comment="comment1" />
<value id="02" text="test2" comment="comment2" />
</values>

</root>
支持(0) 反对(0) heqichang | 园豆:275 (菜鸟二级) | 2012-05-10 17:53
0
 XmlDocument doc = new XmlDocument();
            doc.Load("http://www.cnblogs.com/yukaizhao/rss");
            //使用xPath选择需要的节点
            XmlNodeList nodes = doc.SelectNodes("/rss/channel/item[position()<=10]");
            foreach (XmlNode item in nodes)
            {
                string title = item.SelectSingleNode("title").InnerText;
                string url = item.SelectSingleNode("link").InnerText;
                Console.WriteLine("{0} = {1}", title, url);
            }
中的SelectNodes方法。

http://www.cnblogs.com/yukaizhao/archive/2011/07/25/xpath.html
收获园豆:20
悟行 | 园豆:12559 (专家六级) | 2012-05-10 17:16

我先研究下

支持(0) 反对(0) jhlong | 园豆:21 (初学一级) | 2012-05-10 17:17
0
XElement xe = XElement.Parse("<?xml version=\"1.0\" encoding=\"utf-8\" ?><test>abc<!--注释--><test2>abc<!--注释--></test2></test>");
            IEnumerable<XNode> xlist= xe.Nodes();
            Console.WriteLine(xlist.ElementAt(0));

三行代码搞定

收获园豆:10
az235 | 园豆:8483 (大侠五级) | 2012-05-10 17:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册