【问题标题】:Select Xml Node using Linq to XML使用 Linq to XML 选择 Xml 节点
【发布时间】:2012-04-10 03:48:31
【问题描述】:

我的 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfCustomer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Customer>
        <CustomerId>1f323c97-2015-4a3d-9956-a93115c272ea</CustomerId>
        <FirstName>Aria</FirstName>
        <LastName>Stark</LastName>
        <DOB>1999-01-01T00:00:00</DOB>
    </Customer>
    <Customer>
        <CustomerId>c9c326c2-1e27-440b-9b25-c79b1d9c80ed</CustomerId>
        <FirstName>John</FirstName>
        <LastName>Snow</LastName>
        <DOB>1983-01-01T00:00:00</DOB>
    </Customer>
</ArrayOfCustomer>  

我的尝试:

XElement toEdit = 
    (XElement)doc.Descendants("ArrayOfCustomer")
                 .Descendants("Customer")
                 .Where(x => Guid.Parse((x.Descendants("CustomerId") as XElement).Value) == customer.CustomerId)
                 .First<XElement>();

这会引发以下异常:

 Object reference not set to an instance of an object.

1) x 不是 XElement

2) 这是用于选择 Xml 节点的正确 where lambda 吗?

3) 当然你会如何根据CustomerId找到这个节点?

【问题讨论】:

  • 我首先遇到了异常:无法将“WhereEnumerableIterator`1[System.Xml.Linq.XElement]”类型的对象转换为“System.Xml.Linq.XElement”类型。这是因为我试图从 IEnumrable 转换为单个 XElement ,我向它添加了 First() 扩展。现在它无法将 x 识别为 XElement 。

标签: c# xml lambda linq-to-xml


【解决方案1】:

您的问题是 DescendentsWhere 返回一个 IEnumerable&lt;XElement&gt; 而不是一个 XElement 这就是您所追求的。你可以这样解决这个问题:

XElement toEdit = doc.Descendants("ArrayOfCustomer")
                     .Descendants("Customer")
                     .Where(x => Guid.Parse(x.Descendants("CustomerId").Single().Value) == customer.CustomerId)
                     .FirstOrDefault();

【讨论】:

  • 请注意,这要求客户下只有一个 CustomerId 元素。如果有 0 或 > 1,它将抛出异常。在查看了他的 XML 之后,这可能是合适的。但只是需要指出一点。
  • @AndrewFinnell 在讨论这个问题时,您将如何编辑该节点,我现在可以更新所有客户 (XElement) 的死者,但如何更新文件中的节点?
【解决方案2】:

您不是在投射x,而是在投射x.Descendants()。 x.Descendants() 返回一个集合,因此是复数方法语义。我想你应该可以做到x.Descendants("CustomerId").FirstOrDefault() as XElement

【讨论】:

    【解决方案3】:
    XElement toEdit = (from c in doc.Descendants("Customer")
         where Guid.Parse(c.Value) == customer.CustomerId
         select c).SingleOrDefault();
    

    【讨论】:

      【解决方案4】:

      我会像这样重组您的查询:

       XElement toEdit = doc.Descendants("Customer")
                            .Where(x => (Guid)x.Element("CustomerId") == customer.CustomerId)
                            .FirstOrDefault();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多