如何在c#中使用xelement获取xml节点值

Posted

技术标签:

【中文标题】如何在c#中使用xelement获取xml节点值【英文标题】:How to get xml node value by using xelement in c# 【发布时间】:2021-05-14 06:15:20 【问题描述】:

我有一个如下所示的 XML,我想在其中读取一个名为 1526726702 的节点。因此,这个特定的节点集合 sn-p,我具有列和行结构形式的数据结构。即列由 @987654322 表示@标签和行由<measValue>下的<measResults>表示。所以我有很多单元格,如'Local Cell ID=10'、'Local Cell ID=11'、'Local Cell ID=12'等。现在我的目标是在<measTypes> 部分下读取名为15267267401526728300 的列,以获取第一个单元格“本地单元格ID = 10”的值为43.596390824。像这样,我们有很多特定列的行。如何我可以读取并获取此值吗? XML 片段

<?xml version="1.0" encoding="UTF-8"?>
<measCollecFile xmlns="measCollec" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="Schedule.xsd">
  <fileHeader fileFormatVersion="V7.2" testername="tea">
    <fileSender elementType="SBT900"/>
    <measCollec beginTime="2021-01-24T00:00:00+04:00"/>
  </fileHeader>
  <measData>
    <managedElement userLabel="eelaBldg_474"/>
    <measInfo measInfoId="726702">
    </measInfo>
    <measInfo measInfoId="1526">
    </measInfo>
    <measInfo measInfoId="1526726702">
      <granPeriod duration="PT3600S" endTime="2021-01-24T01:00:00+04:00"/>
      <repPeriod duration="PT3600S"/>
      <measTypes>1526726737 1526726740 1526727483 1526728299 1526728300 1526728301 1526728302 1526728303 1526728304 1526728305  </measTypes>
      <measValue measObjLdn="eelaBldg_474/Cell:eNodeB Function Name=eelaBldg_474, Local Cell ID=10, Cell Name=GhaleelaBldg_A_F1U, eNodeB ID=956474, Cell FDD TDD indication=CELL_TDD">
        <measResults>41.699 43.596 9.241 2461846 390824 27358 0 1263996 5282350 7509028 </measResults>
      </measValue>
      <measValue measObjLdn="eelaBldg_474/Cell:eNodeB Function Name=eelaBldg_474, Local Cell ID=11, Cell Name=GhaleelaBldg_A_F1U, eNodeB ID=956474, Cell FDD TDD indication=CELL_TDD">
        <measResults>42.699 46.596 9.241 2461846 390829 27358 0 1263996 5282350 7509028 </measResults>
      </measValue>
      <measValue measObjLdn="eelaBldg_474/Cell:eNodeB Function Name=eelaBldg_474, Local Cell ID=12, Cell Name=GhaleelaBldg_A_F1U, eNodeB ID=956474, Cell FDD TDD indication=CELL_TDD">
        <measResults>43.699 49.596 9.241 2461846 390826 27358 0 1263996 5282350 7509028 </measResults>
      </measValue>
      
    </measInfo>
  </measData>
</measCollecFile>

我试过的代码如下

 using (XmlReader xr = XmlReader.Create(path))
                
                    xr.MoveToContent();
                    while (xr.Read())
                    
                        while (xr.NodeType == XmlNodeType.Element && xr.LocalName == "measInfo" && xr.GetAttribute("measInfoId") == "1526726702")
                        
                            try
                            
                                XElement pin = (XElement)XNode.ReadFrom(xr);
                                string earfcndl = Getvalue(pin, "measTypes");
                               // string t = pin.Element("measTypes").Value;
    
                                var data = from atts in pin.Elements("measInfo")
                                           select new
                                           
                                               meas = (string)atts.Element("measTypes")
                                           ;
                                string measTypes = data.First().meas;
                            
                            catch (Exception ex)
                            
    
                            
                        
                    
                

【问题讨论】:

【参考方案1】:

您的代码有一个默认命名空间 xmlns="measCollec" 所以使用下面的代码,它使用字典

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;

namespace ConsoleApplication181

    class Program
    
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        
            XDocument doc = XDocument.Load(FILENAME);
            XElement measCollecFile = doc.Root;
            XNamespace ns = measCollecFile.GetDefaultNamespace();

            Dictionary<string,XElement> measInfoDict = measCollecFile.Descendants(ns + "measInfo")
                .GroupBy(x => (string)x.Attribute("measInfoId"), y => y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

            XElement m726702 = (XElement)measInfoDict["1526726702"];

            int numberColumns = ((string)m726702.Descendants(ns + "measResults").FirstOrDefault()).Trim().Split(new char[]  ' ' ).Length;

            string[] strcolumnNames =  "Building", "Cell", "Function Name", "Local Cell ID", "Cell Name", "eNodeB ID", "Cell FDD TDD indication" ;
            DataColumn[] strColumns = strcolumnNames.Select(x => new DataColumn(x, typeof(string))).ToArray();

            DataColumn[] columns = Enumerable.Range(0, numberColumns).Select((x, i) => new DataColumn("Col " + (i + 1).ToString(), typeof(decimal))).ToArray();

            DataTable dt = new DataTable();
            dt.Columns.AddRange(strColumns);
            dt.Columns.AddRange(columns);

            foreach (XElement measValue in m726702.Descendants(ns + "measValue"))
            
                string measObjLdn = (string)measValue.Attribute("measObjLdn");
                int firstSpace = measObjLdn.IndexOf(' ');
                string buildCell = measObjLdn.Substring(0, firstSpace);
                string build = buildCell.Split(new char[]  '/' ).FirstOrDefault();
                string cell = buildCell.Split(new char[]  ':' ).LastOrDefault();
                string parameters = measObjLdn.Substring(firstSpace).Trim();
                string[] parametersValues = parameters.Split(new char[]  ',' ).Select(x => x.Substring(x.IndexOf("=") + 1).Trim()).ToArray();
                parametersValues = (new string[]  build, cell ).Concat(parametersValues).ToArray();
                string values = ((string)measValue.Element(ns + "measResults")).Trim();
                var splitValues = values.Split(new char[]  ' ' ).Select(x => (object)decimal.Parse(x));
                dt.Rows.Add(parametersValues.Concat(splitValues).ToArray());

            

        
    

【讨论】:

我通过使用 XNode.ReadFrom 方法实现了这一点。但我想要的是获取列 '1526726740' 和 '1526728300' 的值。例如,如果我们采用第一个单元格 'Local Cell ID=10' ,我们需要将值设为“43.596”和“390824”。像这么多单元格,我必须采用列“1526726740”和“1526728300”值 它就像魅力一样。还有一件事我怎样才能获得'measValue'的'measObjLdn'的价值

以上是关于如何在c#中使用xelement获取xml节点值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 XElements 列表中删除不需要的节点?

如何使用 XElement 打开 xml?

C#:如何从 XElement 中获取名称(带前缀)作为字符串?

c# foreach 没有在循环中获取下一个 XElement 名称

在 C# Compact Framework 中加速 XML 的解析(使用 XmlTextReader 和 XElement)?

根据特定条件添加Xelement c#