简体   繁体   English

C#遍历xml以获取特定子节点的内部文本值

[英]C# loop through xml to get innertext value of a specific subnode

I have XML document look like this: 我的XML文档如下所示:

<Runs>
 <Run>
  <LotInfo>
   <Column name="Entity">HST123,</Column> 
   <Column name="Product">XXX123</Column> 
   <Column name="WSOp">1234</Column> 
   <Column name="Route">V234</Column> 
   <Column name="Recipe" /> 
   <Column name="LotNumber">K898722</Column> 
   <Column name="RunStartTime">2014-05-20T17:43:11.8872105</Column> 
  </LotInfo>
  <Operations>
   <Operation type="INTRODUCTION">
   <Column name="Size">1490</Column> 
   <Column name="TimeStamp">2014-05-20T17:43:11.8872105</Column> 
   <Column name="Operator">nismail9</Column> 
   <Column name="Description">
    <![CDATA[ Unknown ]]> 
   </Column>
  <Column name="Status">Success</Column> 
  </Operation>
  <Operation type="RNUCHECK">
   <Column name="Size">1490</Column> 
   <Column name="TimeStamp">2014-05-20T17:43:15.3091731</Column> 
   <Column name="Operator">nismail9</Column> 
   <Column name="Description">
    <![CDATA[ ]]> 
   </Column>
   <Column name="Status">True</Column> 
  </Operation>
  <Operations>
   <Operation type="INTRODUCTION">
   <Column name="Size">1490</Column> 
   <Column name="TimeStamp">2014-05-20T17:58:47.0830259</Column> 
   <Column name="Operator">nismail9</Column> 
   <Column name="Description">
    <![CDATA[ Unknown ]]> 
   </Column>
   <Column name="Status">Success</Column> 
   </Operation>
  </Operations>
 </Run>
</Runs>

I want to loop through the whole XML to get the inner text value. 我想遍历整个XML以获取内部文本值。 I need to get the time stamp for the node <Operation type="INTRODUCTION"> . 我需要获取节点<Operation type="INTRODUCTION">时间戳。 Whenever i get the <Operation type="INTRODUCTION"> , I will go to get the time stamp under this node: <Column name="TimeStamp">2014-05-20T17:43:11.8872105</Column> which is 2014-05-20T17:43:11.8872105 . 每当我得到<Operation type="INTRODUCTION"> ,我都会去获取此节点下的时间戳: <Column name="TimeStamp">2014-05-20T17:43:11.8872105</Column> ,即2014-05-20T17:43:11.8872105

I have a code to get the value, but I don't know how to loop through the whole text to get all of them. 我有一个代码来获取值,但是我不知道如何遍历整个文本来获取所有值。 I am only able to get one. 我只能得到一个。

My code so far: 到目前为止,我的代码:

XmlDocument readDoc = new XmlDocument();
            readDoc.Load(fileName);
            int count = readDoc.SelectNodes("/Runs/Run/Operations/Operation[@type='INTRODUCTION']").Count;
            MessageBox.Show(count.ToString());

                        var node = readDoc.SelectSingleNode("/Runs/Run/Operations/Operation[@type='INTRODUCTION']/Column[@name='TimeStamp']");
MessageBox.Show(node.InnerText);

You can get inner Text for all operation nodes using SelectNodes and then iterating over it to get inner text. 您可以使用SelectNodes获取所有操作节点的内部文本,然后对其进行迭代以获取内部文本。

var nodes = readDoc.SelectNodes("/Runs/Run/Operations/Operation/
                                    Column[@name='TimeStamp']");
var innerTexts = nodes.OfType<XmlNode>().Select(n => n.InnerText);

Make sure you add System.Linq namespace to use enumerable extension methods. 确保添加System.Linq命名空间以使用可枚举的扩展方法。

Use XmlDocument.SelectNodes instead of XmlDocument.SelectSingleNode to get all matching nodes. 使用XmlDocument.SelectNodes代替XmlDocument.SelectSingleNode获取所有匹配的节点。 You don't need the count of the nodes, but a list of them. 您不需要节点数,但需要它们的列表。 After you get the nodes, iterate over them using a regular foreach loop construct: 获得节点后,使用常规的foreach循环构造遍历它们:

    var xmlFile = "c:\\input.xml";
    XmlDocument readDoc = new XmlDocument();
    readDoc.Load(xmlFile);
    var nodes = readDoc.SelectNodes("/Runs/Run/Operations/Operation[@type='INTRODUCTION']/Column[@name='TimeStamp']");
    foreach (XmlElement node in nodes)
    {
        Console.WriteLine(node.InnerText);
    }

The output is: 输出为:

2014-05-20T17:43:11.8872105
2014-05-20T17:58:47.0830259

Another possibility would be to use LINQ2XML in order to get the desired nodes: 另一种可能性是使用LINQ2XML以获得所需的节点:

try
{           
    var xmlFile = "c:\\input.xml";
    // load the xml file
    var xml = XDocument.Load(xmlFile);
    // find all operations nodes
    var operations = xml.Root.Descendants("Operations").ToList();
    // iterate over all nodes
    foreach (var operation in operations)
    {
        // find the operation node with type INTRODUCTION
        var op = operation.Elements().Where (o => o.Name == "Operation" && (o.Attribute("type").Value.ToUpper() == "INTRODUCTION")).FirstOrDefault();
        if (op != null)
        {
            // find the timestamp node
            var timestamp = op.Elements().Where (o => o.Name == "Column" && (o.Attribute("name").Value.ToUpper() == "TIMESTAMP")).FirstOrDefault();
            if (timestamp != null)
            {
                // and get the value
                Console.WriteLine(timestamp.Value);
            }
        }
    }
}
catch (Exception exception)
{
    Console.WriteLine(exception.Message);
}

The output is the same as above: 输出与上面相同:

2014-05-20T17:43:11.8872105
2014-05-20T17:58:47.0830259

Using LINQ to XML 使用LINQ to XML

( using System.Xml.Linq; ) using System.Xml.Linq;

var query = XDocument.Load(xmlPath)
    .Descendants("Operation")
    .Where(w => (string)w.Attribute("type") == "INTRODUCTION")
    .SelectMany(s => s.Elements("Column")
        .Where(w => (string)w.Attribute("name") == "TimeStamp")
        .Select(x => (string)x));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM