【问题标题】:Get child node value from xml using xpath使用xpath从xml获取子节点值
【发布时间】: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 会帮助你

标签: c# .net xml


【解决方案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);
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 2015-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多