【问题标题】:Exception querying XML using linq使用 linq 查询 XML 的异常
【发布时间】:2012-06-17 12:38:11
【问题描述】:

我之前问过这个问题,我得到了非常快速和有用的回复:Linq to XML query not picking up any values

我遵循了标记为正确的答案中给出的建议,该建议有效并允许我选择“产品”标签。我现在在那个“产品”标签中搜索,以便找到要导入我的数据库的值,但我又有点卡住了。

这是我的 XML 文件的结构:

<?xml version="1.0"?>
<!DOCTYPE ONIXMessage SYSTEM "http://www.editeur.org/onix/2.1/reference/onix-international.dtd">
<ONIXMessage xmlns="http://www.editeur.org/onix/2.1/reference" release="2.1">
  <Header>
    <FromCompany>MyCo</FromCompany>
    <FromPerson>Joe Bloggs</FromPerson>
    <FromEmail>joe@bloggs.com</FromEmail>
    <SentDate>20120522</SentDate>
  </Header>
  <Product>
    <ProductForm>DG</ProductForm>
    <Title>
      <TitleType>01</TitleType>
      <TitleText>Blogg</TitleText>
    </Title>
    <WorkIdentifier>
      <WorkIDType>15</WorkIDType>
      <IDValue>PI3564231</IDValue>
    </WorkIdentifier>
    <Language>
      <LanguageRole>01</LanguageRole>
      <LanguageCode>eng</LanguageCode>
    </Language>
  </Product>
</ONIXMessage>

这是我的代码中的 sn-p:

        XElement onix = XElement.Load(fs);

        // Get all the product information.
        //
        var products = onix.Descendants().Where(m => m.Name.LocalName == "Product").ToList();

        foreach (var p in products)
        {
            try
            {
                prod.Title = p.Elements("Title").First(t => (t.Element("TitleType").Value == "01")).Element("TitleText").Value;
                //further processing
            }
            catch (Exception exp)
            {
                throw new FileProcessingException("Unable to process product.", exp);
            }
        }

当我搜索如上所示的标题文本时,异常被捕获。例外是“对象引用未设置为对象的实例”。该项目显然在 XML 文件中,只是没有正确提取它。

在 toda 之前我从未见过 .Descendants() 并且我明白它的含义,但是从我读到的内容中,我应该也可以在这里使用 .Elements() 吗?

谁能看出哪里出了问题?

【问题讨论】:

  • 你能告诉我们错误发生在哪里以及异常说明了什么吗?
  • 另外,.First() 很棘手,因为如果没有找到它会抛出异常。 .FirstOrDefault() 如果没有找到任何内容,将返回 Null,如果您不测试 Null,仍然会导致 NullReferenceException。
  • 如果您在失败的行上放置一个断点并评估p.Element("Title"),它是否包含任何元素?如果您评估p.Elements("Title").First(t =&gt; (t.Element("TitleType").Value == "01")),那么异常来自哪里?
  • @Cyborgx37 - 刚刚编辑了我的帖子,但有例外...
  • 听起来您需要单步调试代码并进行一些测试。设置断点并寻找错误的来源。您的问题基本上是让我们在您的代码中寻找错误,这并不是一个真正的技术问题。此外,请阅读 MSDN 上的 XML 文档。 msdn.microsoft.com/en-us/library/bb387098.aspx

标签: c# asp.net linq linq-to-xml


【解决方案1】:

试试这个:

    XDocument doc = XDocument.Load(fs);
 var products= from elements in doc.Elements("ONIXMessage").Elements("Product");
   foreach (var p in products)
            {
                    var title  = (from items in p.Elements("Title")
                                 where items.Element("TitleType").Value == "01"
                                 select items.Element("TitleText").Value).FirstOrDefault();
            }

【讨论】:

  • 感谢您的回复。我尝试了上面的示例,不再抛出异常,但是该字段现在只填充了“null”,因此无论出于何种原因,linq 都没有正确获取 XML。
【解决方案2】:

好吧,正如我回答了你之前的问题,我想我可能会有所帮助......

您的文档有一个命名空间 (xmlns)。 如果你想使用 Elements("tagName") 或 Element("tagName") 等,你必须在你所有的 TagName 前面加上命名空间。

如果您这样做,您的查询将起作用(如 Habib.OSU 在您之前的问题中所述)

  XNamespace ns = onix.Attribute("xmlns").Value;
  var products2 = onix.Elements(ns + "Product").ToList();

  foreach (var p in products2)
  {
        var title = p.Elements(ns + "Title")
        .First(t => (t.Element(ns + "TitleType").Value == "01"))
        .Element(ns + "TitleText").Value;
  }

如果您绝对不想使用命名空间,则必须使用 Descendants() 和 Name.LocalName。它会给你同样的,但是......它真的很难阅读。

 var products = onix.Descendants().Where(m => m.Name.LocalName == "Product").ToList();

 foreach (var p in products)
 {

      var title = p.Descendants().Where(m => m.Name.LocalName == "Title")
         .Descendants()
         .First(m => m.Name.LocalName == "TitleType" && m.Value == "01")
         .Parent
         .Descendants()
         .First(m => m.Name.LocalName == "TitleText")
         .Value;

 }

我没有放任何 NULL Check,这当然是要做的事情。

还要注意,第二个查询的性能会降低,因为 Descendants() 会枚举元素的所有子元素,而不考虑层次结构。而 Elements() 将仅检索直接子节点。

【讨论】:

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