C# 如何使用LInq c从xml中的多个相同元素中获取所需的值#

C# 如何使用LInq c从xml中的多个相同元素中获取所需的值#,c#,xml,linq,C#,Xml,Linq,我正在解析一个包含节点的XML文件。有时这些节点直接在节点中找到,有时在和节点中更深层地找到 我直接在节点中查找节点的值 我的XML是 <?xml version="1.0" encoding="utf-8" ?> <xn:VsDataContainer id=test"> <xn:attributes> <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType> <e

我正在解析一个包含
节点的XML文件。有时这些节点直接在
节点中找到,有时在
节点中更深层地找到

我直接在
节点中查找
节点的值

我的XML是

<?xml version="1.0" encoding="utf-8" ?>
<xn:VsDataContainer id=test">
  <xn:attributes>
    <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
    <es:crsGain>0</es:crsGain>
    <es:pciConflictCell>
      <es:enbId>66111</es:enbId>
      <es:qrxlev>3</es:qrxlev>
    </es:pciConflictCell>
    <es:pciConflictCell>
      <es:enbId>66111</es:enbId>
      <es:qrxlev>7</es:qrxlev>
    </es:pciConflictCell>
    <es:pciDictictCell>
      <es:enbId>66111</es:enbId>
      <es:qrxlev>8</es:qrxlev>
    </es:pciDictictCell>
    <es:pdcchLaGinrMargin>100</es:pdcchLaGinrMargin>
    <es:lbEUtranAcceptOffloadThreshold>50</es:lbEUtranAcceptOffloadThreshold>
    <es:pdcchCfiMode>5</es:pdcchCfiMode>
    <es:qrxlev>10</es:qrxlev>
    <es:zzzTemporary21>-2000000000</es:zzzTemporary21>
  </xn:attributes>
</xn:VsDataContainer>


不要使用获取树中所有节点的
子体()。使用
Elements()
,它获取当前节点的直接子节点

var xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
    <xn:VsDataContainer id=""test"" xmlns:xn=""xn"" xmlns:es=""es"">
      <xn:attributes>
        <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
        <es:crsGain>0</es:crsGain>
        <es:pciConflictCell>
          <es:enbId>66111</es:enbId>
          <es:qrxlev>3</es:qrxlev>
        </es:pciConflictCell>
        <es:pciConflictCell>
          <es:enbId>66111</es:enbId>
          <es:qrxlev>7</es:qrxlev>
        </es:pciConflictCell>
        <es:pciDictictCell>
          <es:enbId>66111</es:enbId>
          <es:qrxlev>8</es:qrxlev>
        </es:pciDictictCell>
        <es:pdcchLaGinrMargin>100</es:pdcchLaGinrMargin>
        <es:lbEUtranAcceptOffloadThreshold>50</es:lbEUtranAcceptOffloadThreshold>
        <es:pdcchCfiMode>5</es:pdcchCfiMode>
        <es:qrxlev>10</es:qrxlev>
        <es:zzzTemporary21>-2000000000</es:zzzTemporary21>
      </xn:attributes>
    </xn:VsDataContainer>";

XNamespace xnNamespace = "xn";
XNamespace esNamespace = "es";

var xmlElement = XElement.Parse(xml);
var qrxlev = xmlElement
    .Element(xnNamespace + "attributes")
    .Element(esNamespace + "qrxlev")
    .Value;
var xml=@”
vsDataEUtranCellFDD
0
66111
3.
66111
7.
66111
8.
100
50
5.
10
-2000000000
";
XNamespace xnNamespace=“xn”;
XNamespace esNamespace=“es”;
var xmlement=XElement.Parse(xml);
var qrxlev=xmlElement
.Element(xnNamespace+“属性”)
.Element(esNamespace+“qrxlev”)
价值
这将返回第四个
元素的值
10

我必须对您的xml进行一些修改:

  • 您没有声明任何名称空间
  • 您的
    test
    属性引用不正确

如果需要最高级别的定义,请在树中创建一个查找节点级别的方法,如下所示:

static int GetDocLevel(XElement e) {
    var res = 0;
    while (e != null) {
        res++;
        e = e.Parent;
    }
    return res;
}
现在,您可以按级别排序,并选择最上面的一个:

XNamespace esNs = "http://www.es.org"; // <<== The actual namespace goes here
var topQrxlev = doc.Descendants(esNs + "qrxlev").OrderBy(GetDocLevel).FirstOrDefault();

XNamespace esNs=”http://www.es.org"; // 这是一个巨大的文件,我正在将所需的部分分配到c#类中,然后进行处理。这对类有效吗???也许?我得看看你们的课才能知道。但是,如果您使用XElement进行xml解析(看起来是这样的),那么它应该很好。去试一试。如果我在现有代码中使用like qrxlev=(int)x.Element(un+“cellId”),我得到的错误值不能为null。有没有办法找到直接的子值
XNamespace esNs = "http://www.es.org"; // <<== The actual namespace goes here
var topQrxlev = doc.Descendants(esNs + "qrxlev").OrderBy(GetDocLevel).FirstOrDefault();
class Program {
    static int GetDocLevel(XElement e) {
        var res = 0;
        while (e != null) {
            res++;
            e = e.Parent;
        }
        return res;
    }

    static void Main(string[] args) {
        var xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<xn:VsDataContainer
    xmlns:es=""http://www.es.org""
    xmlns:xn=""http://www.xn.org""
>
<xn:attributes>
  <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
  <es:crsGain>0</es:crsGain>
  <es:pciConflictCell>
    <es:enbId>66111</es:enbId>
    <es:qrxlev>3</es:qrxlev>
  </es:pciConflictCell>
  <es:pciConflictCell>
    <es:enbId>66111</es:enbId>
    <es:qrxlev>7</es:qrxlev>
  </es:pciConflictCell>
  <es:pciDictictCell>
    <es:enbId>66111</es:enbId>
    <es:qrxlev>8</es:qrxlev>
  </es:pciDictictCell>
  <es:pdcchLaGinrMargin>100</es:pdcchLaGinrMargin>
  <es:lbEUtranAcceptOffloadThreshold>50</es:lbEUtranAcceptOffloadThreshold>
  <es:pdcchCfiMode>5</es:pdcchCfiMode>
  <es:qrxlev>10</es:qrxlev>
  <es:zzzTemporary21>-2000000000</es:zzzTemporary21>
</xn:attributes>
</xn:VsDataContainer>";
        var doc = XDocument.Parse(xml);
        XNamespace esNs = "http://www.es.org";
        var topQrxlev = doc.Descendants(esNs + "qrxlev").OrderBy(GetDocLevel).FirstOrDefault();
        Console.WriteLine(topQrxlev?.Value); // Prints 10
    }

}