I asked this question earlier and I got very quick and helpful responses: Linq to XML query not picking up any values
I followed the advice as given in the answer marked as correct which worked and allowed me to pick up the ‘Product’ tags. I am now searching within that ‘Product’ tag in order to find values to import into my database and I’m a bit stuck again.
Here is the structure of my XML file:
<?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>
Here is the snippet from my code:
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);
}
}
When I search for the Title text as shown above, the exception is caught. The exception is “Object reference not set to an instance of an object.” The item is clearly in the XML file, it just isn’t picking it up right.
I had never seen .Descendants() before toda and I get what it means, but from what I read I should be able to use .Elements() here also?
Can anyone see what could be wrong?
Well, as I answered your previous question, I think I might help…
Your document has a namespace (xmlns).
If you wanna use Elements(“tagName”) or Element(“tagName”), etc, you have to prefix all your TagName By the namespace.
so your query will work (as mentioned by Habib.OSU in your previous question), if you do
if you absolutely don’t wanna use the namespace, you have to use Descendants() and Name.LocalName. It’ll give you the same, but… it’s really hard to read.
I didn’t put any NULL Check, this would be, of course, something to do.
Also note that the second query will be less performant, as Descendants() enumerates all subElements of an elements, without taking care of hierarchy. While Elements() will retrieve the direct child Nodes only.