首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用LInq c#从xml中的多个相同元素获取所需的值

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

Stack Overflow用户
提问于 2017-10-02 15:23:57
回答 2查看 96关注 0票数 0

我正在解析一个包含<es:qrxlev>节点的XML文件。有时这些节点直接在<xn:attributes>节点中找到,有时它们被发现得更深,比如在<es:pciConflictCell><es:pciDictictCell>节点中。

我直接在<es:qrxlev>节点中跟踪<xn:attributes>节点的值。

我的XML是

代码语言:javascript
复制
<?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>

我现在使用的代码是:

代码语言:javascript
复制
List<XElement> vsDataEUtranCellFDD = vsDataContainers.Where(x => x.Descendants().Where(a => (a.Name.LocalName == "vsDataType") && ((string)a == "vsDataEUtranCellFDD")).Any()).ToList();

     List<CellName> cells = vsDataEUtranCellFDD.Select(x => new CellName()
                                                {
    if (vsDataEUtranCellFDD.Any()) 
    {
        List<CellName> cells = vsDataEUtranCellFDD
            .Select(x => new CellName() 
            {
                qrxlev= (int)x.Descendants()
                    .Where(a => a.Name.LocalName == "qrxlev")
                    .FirstOrDefault()
            };
    }

此代码的问题在于它返回所有<es:qrxlev>节点值,而不仅仅是属性节点中的值。如何才能只得到我想要的特定值,而不是所有的值?

EN

回答 2

Stack Overflow用户

发布于 2017-10-02 15:47:30

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

代码语言:javascript
复制
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;

这将返回10,第四个<es:qrxlev>元素的值。

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

  • 您没有声明任何名称空间
  • 您的test属性引用不当
票数 1
EN

Stack Overflow用户

发布于 2017-10-02 16:02:26

如果希望获得最高级别的定义,请创建一个方法来查找树中的节点级别,如下所示:

代码语言:javascript
复制
static int GetDocLevel(XElement e) {
    var res = 0;
    while (e != null) {
        res++;
        e = e.Parent;
    }
    return res;
}

现在您可以按级别进行排序,并取前一位:

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

下面是一个正在运行的示例:

代码语言:javascript
复制
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
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46528601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档