C# 使用linq查询XML时发生异常
我早些时候问过这个问题,得到了非常迅速和有益的回答: 我遵循了答案中给出的建议,答案被标记为正确,有效地让我拿起了“产品”标签。我现在正在“产品”标签中搜索,以便找到要导入到数据库中的值,我又有点卡住了 以下是我的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 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;
}