使用LINQ选择是否存在XML元素

时间:2013-07-06 13:52:02

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

我有以下xml。由于addr在这种情况下是空的,但大部分时间它都有街道,城市,州等元素。我如何确保它存在。现在的原因LINQ查询抛出错误“对象引用未设置为对象的实例。”

  <author>
    <time value="20120620153233"/>
    <assignedAuthor>
      <id/>
      <addr/>
      <telecom value="tel:+1-781-271-3000"/>
      <assignedPerson>
        <name>Auto Generated</name>
      </assignedPerson>
    </assignedAuthor>
  </author>



 tbAuthor autor =
                    (from c in cdafile.Root.Elements(ns + "author")
                    select new tbAuthor
                    {                           
                        streetAddressLine = (string)c.Element(ns + "assignedAuthor").Element(ns + "addr").Element(ns + "streetAddressLine").Value,
                        city = (string)c.Element(ns + "assignedAuthor").Element(ns + "addr").Element(ns + "city").Value,
                        state = (string)c.Element(ns + "assignedAuthor").Element(ns + "addr").Element(ns + "state").Value,
                        postalCode = (string)c.Element(ns + "assignedAuthor").Element(ns + "addr").Element(ns + "postalCode").Value,
                        country = "US"
                    }).FirstOrDefault();

2 个答案:

答案 0 :(得分:0)

一种方法是使用内联if

    streetAddressLine = (string)c.Element(ns + "assignedAuthor").Element(ns + "addr") == null ? "" : c.Element(ns + "assignedAuthor").Element(ns + "addr").Element(ns + "streetAddressLine").Value

答案 1 :(得分:0)

如果路径中的任何部分不存在,您可以使用these extensions来提供默认值。 Get中的最后一个路径部分可以是元素或属性。它还将为您找出命名空间。

tbAuthor author =
    (from c in cdafile.Root.Elements(ns + "author")
    select new tbAuthor
    {                           
        streetAddressLine = c.Get("assignedAuthor/addr/streetAddressLine", "default"),
        city = c.Get("assignedAuthor/addr/city", "default"),
        state = c.Get("assignedAuthor/addr/state", "default"),
        postalCode = c.Get("assignedAuthor/addr/postalCode", "default"),
        country = "US"
    })
    .FirstOrDefault();

或者您可以使用the whole library并以这种方式编写(假设没有其他地址子元素可以提供与所需内容不同的结果):

tbAuthor author =
    (from c in cdafile.Root.Elements(ns + "author")
    select new tbAuthor
    {                           
        streetAddressLine = c.XGetElement(".//streetAddressLine", "default"),
        city = c.XGetElement(".//city", "default"),
        state = c.XGetElement(".//state", "default"),
        postalCode = c.XGetElement(".//postalCode", "default"),
        country = "US"
    })
    .FirstOrDefault();