通过属性值访问 xml 元素

Posted

技术标签:

【中文标题】通过属性值访问 xml 元素【英文标题】:access xml element by attribute value 【发布时间】:2011-10-31 21:24:18 【问题描述】:

可能这个问题重复了,但我对现有的答案并不满意。我想通过属性值从动态生成的 xml 文件中获取 xml 元素。我们不知道有多少节点,以及它的层次结构。但是每个元素,它的子元素,它的子子元素,子子子元素......等等都将包含唯一的 guid 作为“Id”属性:

    <Element id="">
  <SubElement id=""></SubElement>
  <SubElement id="">
    <SubSubElement id="">
      <SubSubSubElement id="">
        <SubSubSubSubElement id="">....other sub inside this ...</SubSubSubSubElement>
      </SubSubSubElement>
    </SubSubElement>
  </SubElement>
</Element>

我只想通过传递 Guid 值来查找元素。不管它的xpath,它的节点位置/位置。我怎么能在 C# 中做到这一点?我需要使用 LINQ 吗?

已编辑:

 XDocument xmldoc = XDocument.Load(xmlFilePath);
XElement selectedElement = xmldoc.Descendants().Where(x => (string) x.Attribute("id") == myIdvalue).FirstOrDefault(); 

例外: “表达式不能包含 lambda 表达式” 我添加了使用 System.Linq 命名空间。

【问题讨论】:

【参考方案1】:

hoipolloi 给出了 XPath 答案,这很好 - 但我个人会使用 LINQ to XML。 (见my blog post on code and data for reasons。)

var element = parent.Descendants()
                    .Where(x => (Guid?) x.Attribute("id") == id)
                    .FirstOrDefault();

这将对每个 id 属性执行适当的 GUID 解析(为非 GUID 返回“null”Guid? 值)。如果您确定 ID 的文本格式,则可以转换为字符串:

var element = parent.Descendants()
                    .Where(x => (string) x.Attribute("id") == idText)
                    .FirstOrDefault();

根据您的要求将FirstOrDefault 更改为SingleSingleOrDefaultFirst

编辑:完全不清楚您发布的代码出了什么问题。这是一个简短但完整的程序,表明它运行良好。请将此与您的代码进行比较:

using System;
using System.Linq;
using System.Xml.Linq;

class Test

    static void Main()
    
        string xml = "<parent><foo id='bar' /><foo id='baz' /></parent>";
        XDocument doc = XDocument.Parse(xml);
        string idToFind = "bar";
        XElement selectedElement = doc.Descendants()
            .Where(x => (string) x.Attribute("id") == idToFind).FirstOrDefault();
        Console.WriteLine(selectedElement);
    

【讨论】:

使用LINQ有什么好处?自 .NET 1.2 以来,我还没有使用 C# 进行开发。仅供参考,我刚买了你的书来让自己跟上 4 的速度。:) @hoipolloi:我发现让 data 部分远离 code 部分很有帮助 - 编译器可以在编译时检测语法错误,您知道方法(Descendants 等)确实会存在 - 所有延迟到执行时间的都是真正的数据相关方面。 LINQ to XML 也使命名空间处理变得轻而易举:) @Jon Skeet:我已经尝试过这些表达式,但我得到“表达式不能包含 lambda 表达式”。如果我是对的,那么“父级”必须是加载了 xml 文档的 XDocument 对象。为什么我应该得到这个异常? @Red Swan:请展示一个简短但完整的程序来说明问题。应该没问题的。 @Red Swan:您的代码尝试强制转换为无效类型 string? - 您只能使用 ? 作为不可为空值类型的后缀。【参考方案2】:

您可以使用 XPath 来执行此操作。例如,以下匹配所有 id 为 'foo' 的元素,无论它们在文档中的位置如何:

//*[@id='foo']

【讨论】:

它运行良好。但是有没有办法通过 LINQ 或任何实体框架对象 medel 来实现这一点?

以上是关于通过属性值访问 xml 元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 Java 解析 XML 并获取元素值和属性值

sqlserver for xml

具有相同元素名称但属性值不同的XML的XSD架构[关闭]

Dom解析xml,只是简单的解析出有效元素的元素名,元素值,属性名和属性值

xmlstarlet 通过属性而不是元素匹配/解析

将 xml 值绑定为属性或元素