【问题标题】:Select if exist XML Element using LINQ使用 LINQ 选择是否存在 XML 元素
【发布时间】:2013-07-06 23:53:56
【问题描述】:

我有以下 xml 。由于在这种情况下 addr 是空的,但大多数时候它具有诸如 street,city,state 之类的元素。我如何确保它存在。因为现在 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();

【问题讨论】:

  • ns 变量中有什么?

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


【解决方案1】:

如果路径中的任何部分不存在,您可以使用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();

【讨论】:

  • 谢谢!看起来这就是我要找的东西。
  • 这行得通,但我有一些其他元素有一些 HTML 作为内容。它剥离 HTML 内容并仅返回 text 。我能做什么?
  • @user1649941 您应该将其作为单独的问题发布。然而,据我了解,HTML 不是正确的 XML,因此必须将整个文件视为 HTML。
  • @user1649941 您可以尝试扩展 GetElement 来获取具有 HTML 的父元素,如果该元素不存在,它将查找或创建该元素,因此您没有空引用。然后,如果可能,您可以操纵该元素以获取它包含的 HTML。在没有看到有问题的节点的情况下,我可以提供一些建议,这就是为什么您应该发布另一个问题来解决您的问题。
【解决方案2】:

一种方法是使用 inline if

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

【讨论】:

  • 它仍然显示错误,我认为是因为根本不存在 streetAddressLine 元素。
  • 您是否将内联 if 应用于所有属性(城市、州、邮政编码)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
相关资源
最近更新 更多