Reputation: 708
I have an XML file that looks like this...
<return>
<availableOptions>
<premiums>
<item>
<productCode>Poroduct Code 1</productCode>
<productDescription>Product Desc 1</productDescription>
<coverageCode>Coverage Code 1</coverageCode>
<coverageDescription>Coverage Description 1</coverageDescription>
</item>
<item>
<productCode>Poroduct Code 2</productCode>
<productDescription>Product Desc 2</productDescription>
<coverageCode>Coverage Code 2</coverageCode>
<coverageDescription>Coverage Description 2</coverageDescription>
<coverageOptions>
<item>
<label>label here</label>
<value>true</value>
<key>key</key>
</item>
<item>
<label>label here</label>
<value>true</value>
<key>key</key>
</item>
</coverageOptions>
<surcharges/>
</item>
<item>
etc...
</item>
<item>
etc...
</item>
</premiums>
</availableOptions>
</return>
My goal is to: find all the unique coverageCodes
I have the following LINQ code:
XDocument xdoc = XDocument.Load("data.xml");
var linq = from item in xdoc.Descendants("premiums").Descendants("item")
select new
{
ProductCode = item.Element("productCode").Value,
CoverageCode = item.Element("coverageCode").Value
};
foreach (var node in linq)
{
Console.WriteLine("Product Code: " + node.ProductCode + ", Coverage Code: " + node.CoverageCode);
}
The first <item>
outputs correctly. However, when it gets to the second <item>
it throws an error Object reference not set to an instance of an object
because it's looking for the productCode
and coverageCode
in the coverageOptions/item
node, but there isn't any.
I do not want it to look there.
How can i have the LINQ just focus on the first <item>
instead? I also would like the productCode and coverageCode to be distinct. In this XML file, there are multiple <item>
that have the same productCode and coverageCode nodes.
Thank you very much in advance!
Upvotes: 0
Views: 226
Reputation: 1499770
How can i have the LINQ just focus on the first
<item>
instead?
I assume you don't just want the very first <item>
, but each top-level <item>
. Just change Descendants("item")
to Elements("item")
. That way it will only look for immediate children of premiums
instead of all descendant elements.
For the distinct part, you should be able to just use linq.Distinct()
. Anonymous types implement equality and hash code generation appropriately. (It will only look for distinct combinations, mind you - if you have two items with the same product code but different coverage codes for example, they will still be viewed as distinct.)
Upvotes: 3