views:

42

answers:

4

I have a block of XML similar to the following:

<factsheet>
<bilcontents >
  <config name="1" />
</bilcontents>

<singlefactsheet includeInBook="true">
  <config name="7" />
  <fund id="630" />
</singlefactsheet>

<doubleFactsheet includeInBook="true">
  <config name="8" />
  <fund id="623" />
  <fund id="624" />
</doubleFactsheet>

<tripplefactsheet includeInBook="true">
  <config name="6" />
  <fund id="36" />
  <fund id="37" />
  <fund id="38" />
</tripplefactsheet>
</factsheet>

Is it possible for me to get a list of XElements that contains each of these, as long as includeInBook="true", and with each element I can then deal with it based on the type of node.

+1  A: 

Absolutely:

 var list = doc.Root
               .Elements()
               .Where(x => (bool?) x.Attribute("includeInBook") == true)
               .ToList();

Dealing with nullable Booleans can be a little odd, btw. An alternative approach for the lambda expression could be:

x => (bool?) x.Attribute("includeInBook") ?? false

or

x => (string) x.Attribute("includeInBook") == "true"
Jon Skeet
Thanks Jon, I actually worked out something similar on my own so I posted it below.
DaveDev
A: 

This is what I worked out, though Jon pretty much beat me to the punch

var inBook = nodes.Descendants()
    .Where(xx => xx.Attribute("includeInBook") != null)
    .Select(xx => xx).ToList();
DaveDev
That's only verifying whether the attribute *exists* - if would include `includeInBook="false"` elements which is surely not what you want. Note also that the `Select` call is redundant.
Jon Skeet
Points taken. Thanks
DaveDev
A: 

Alternately, you could use the built-in XPath extension methods methods (they live in System.Xml.Xpath:

XDocument doc;
// ...
var includeInBook = doc.XPathSelectElements("/factsheet/*[@includeInBook = 'true']")

Read as:

  • /factsheet: select the element 'factsheet'
  • /*: then choose all children
  • [ ... ]: read square brackets as "where"
    • @includeInBook = 'true': the attribute "includeInBook" has content equal to 'true'
Porges
A: 

You should consider creating data structures for this XML and using "serialization". This would be a much cleaner way to interact with this data model. Just something to consider...

Robert Seder