我之前提出过这个问题,我得到了非常快速和有帮助的回复:Linq to XML query not picking up any values
我按照标记为正确的答案中给出的建议起作用,并允许我拿起“产品”标签。我现在在'Product'标签内搜索,以便找到要导入我的数据库的值,我又有点卡住了。
以下是我的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>
以下是我的代码中的代码段:
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()在这里呢?
任何人都可以看到可能出错的地方吗?
答案 0 :(得分:1)
好吧,当我回答你上一个问题时,我想我可能会帮忙......
您的文档有一个命名空间(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检查,这当然是可以做的事情。
另请注意,第二个查询的性能较差,因为Descendants()枚举元素的所有子元素,而不考虑层次结构。而Elements()只会检索直接子节点。
答案 1 :(得分:0)
试试这个:
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();
}