使用xpath从xml获取子节点值
Posted
技术标签:
【中文标题】使用xpath从xml获取子节点值【英文标题】:Get child node value from xml using xpath 【发布时间】:2018-06-27 09:46:04 【问题描述】: <Demo_Test>
<Step ID="1">
<ACTION>Point</ACTION>
<CLASS_ID>dfsfsdf</CLASS_ID>
</Step>
<Step ID="2">
<ACTION>Point</ACTION>
<CLASS_ID>Avkddd</CLASS_ID>
</Step>
<Step ID="3">
<ACTION>Point</ACTION>
<CLASS_ID>afsasfa</CLASS_ID>
</Step>
<Step ID="4">
<ACTION>SubAction</ACTION>
<CLASS_ID>afsasfa</CLASS_ID>
</Step>
</Demo_Test>
我想修改“动作”节点值为“点”的“CLASS_ID”的值 为此,我写了下面的代码但不起作用
string l_xPath = "//Step/ACTION["Point"]";
XmlNodeList l_nodeList = l_doc.SelectNodes(l_xPath);
【问题讨论】:
也许this 会帮助你 【参考方案1】:使用 xml linq 我将结果放入字典中
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
class Program
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
XDocument doc = XDocument.Load(FILENAME);
Dictionary<int, string> dict = doc.Descendants("Step")
.Where(x => (string)x.Element("ACTION") == "Point")
.GroupBy(x => (int)x.Attribute("ID"), y => (string)y.Element("CLASS_ID"))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
【讨论】:
我不确定创建结果的最佳方法是什么。一个字典,您可以毫无问题地修改值。如果您的输出是相同的 xml 格式,我可以修改代码以枚举元素并修改值。【参考方案2】:你可以用这个:
var l_nodeList = l_doc.SelectNodes("//Step[ACTION='Point']");
foreach (XmlNode item in l_nodeList)
Console.WriteLine(item.SelectSingleNode("CLASS_ID").InnerText);
但我更喜欢jdweng的回答
【讨论】:
【参考方案3】:首先你需要一个像这样的对象:
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
[XmlRoot(ElementName="Step")]
public class Step
[XmlElement(ElementName="ACTION")]
public string ACTION get; set;
[XmlElement(ElementName="CLASS_ID")]
public string CLASS_ID get; set;
[XmlAttribute(AttributeName="ID")]
public string ID get; set;
[XmlRoot(ElementName="Demo_Test")]
public class Demo_Test
[XmlElement(ElementName="Step")]
public List<Step> Step get; set;
那么你可以用这个方法对xml进行反序列化:
public static T XmlDeserializer<T>(string xmlString)
var instance = default(T);
var xmlSerializer = new XmlSerializer(typeof(T));
using (var stringreader = new StringReader(xmlString))
instance = (T)xmlSerializer.Deserialize(stringreader);
return instance;
然后像这样使用它:
var result = XmlDeserializer<Demo_Test >("your xml string here");
var l_nodeList =result.Step[0].CLASS_ID;
【讨论】:
@Jaques,实际上你需要的代码只有一行——反序列化。 OP 没有提到解决方案的使用地点和方式。您可以为每个小任务编写 xpath 或 xml linq 查询,但仅创建表示模式的一两个类将使 xpath 变得多余。【参考方案4】:此解决方案使用 XPath 实现
XmlDocument d = new XmlDocument();
d.Load(@"C:\Users\Desktop\test.xml");
XPathNavigator nav = d.CreateNavigator();
XPathExpression exp;
exp = nav.Compile("//Step[ACTION='Point']");
XPathNodeIterator iterator = nav.Select(exp);
var a = d.SelectNodes("//Step[ACTION='Point']");
while (iterator.MoveNext())
Console.WriteLine(iterator.Current.SelectSingleNode("CLASS_ID").Value);
【讨论】:
以上是关于使用xpath从xml获取子节点值的主要内容,如果未能解决你的问题,请参考以下文章