C# 使用linq查询XML时发生异常

C# 使用linq查询XML时发生异常,c#,asp.net,linq,linq-to-xml,C#,Asp.net,Linq,Linq To Xml,我早些时候问过这个问题,得到了非常迅速和有益的回答: 我遵循了答案中给出的建议,答案被标记为正确,有效地让我拿起了“产品”标签。我现在正在“产品”标签中搜索,以便找到要导入到数据库中的值,我又有点卡住了 以下是我的XML文件的结构: <?xml version="1.0"?> <!DOCTYPE ONIXMessage SYSTEM "http://www.editeur.org/onix/2.1/reference/onix-international.dtd"> &l

我早些时候问过这个问题,得到了非常迅速和有益的回答:

我遵循了答案中给出的建议,答案被标记为正确,有效地让我拿起了“产品”标签。我现在正在“产品”标签中搜索,以便找到要导入到数据库中的值,我又有点卡住了

以下是我的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>
当我搜索如上所示的标题文本时,异常被捕获。例外情况是“对象引用未设置为对象的实例”。该项显然在XML文件中,只是没有正确地拾取它

我在toda之前从未见过.subjections(),我明白了它的含义,但从我读到的内容来看,我应该也能在这里使用.Elements()

有人能看出哪里出了问题吗?

试试这个:

    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();
            }

好吧,我回答了你之前的问题,我想我可能会帮你

您的文档具有名称空间(xmlns)。 如果要使用元素(“标记名”)或元素(“标记名”)等,则必须按名称空间为所有标记名添加前缀

因此,如果您这样做,您的查询将起作用(正如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;
  }
如果绝对不想使用名称空间,则必须使用后代()和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;

 }
我没有设置任何空检查,这当然是有必要的


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

您能告诉我们错误发生的确切位置以及异常说明吗?另外,.First()很棘手,因为如果找不到任何内容,它将引发异常。如果未找到任何内容,FirstOrDefault()将返回Null,如果不测试Null,这仍然会导致NullReferenceException。如果在失败的行上放置断点并计算
p.Element(“Title”)
,它是否包含任何元素?如果您先评估
p.Elements(“Title”)。首先(t=>(t.Element(“TitleType”).Value==“01”)
这就是异常产生的原因吗?@Cyborgx37-刚刚编辑了我的文章,但出现了异常…听起来您需要逐步检查代码并进行一些测试。设置断点并查找错误源。您的问题基本上是让我们查找代码中的bug,这不是一个真正的技术问题。另外,请阅读MSDN上的XML文档。谢谢你的回复。我尝试了上面的示例,不再抛出异常,但是该字段现在只填充了“null”,因此无论出于什么原因,linq都没有正确地提取XML。
 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;

 }