Zero
Zero

Reputation: 118

Skip children in XmlReader C#

I have the following XML

<Company name="Kinanah Computers">
  <Computer Name="Computer" type="Dell">
      <Accessory type="screen" model="dell"/>
      <Accessory type="mouse" model="dell"/>
      <Accessory type="keyboard" model="dell"/>
  </Computer>
  <Computer Name="Computer" type="HP">
        <Accessory type="screen" model="hp"/>
        <Accessory type="mouse" model="chinese"/>
        <Accessory type="keyboard" model="dell"/>
  </Computer>
  <Computer Name="Computer" type="HP">
        <Accessory type="screen" model="hp"/>
        <Accessory type="mouse" model="chinese"/>
        <Accessory type="keyboard" model="dell"/>
  </Computer>
  <Computer Name="Computer" type="acer">
        <Accessory type="screen" model="acer"/>
        <Accessory type="mouse" model="acer"/>
        <Accessory type="keyboard" model="acer"/>
  </Computer>
</Company>

what I want to do, is to skip the HP computer if its type is HP, can anybode tell me how to do that?

I'm using the following C# code :

var stream = new StringReader(instanceXml/*the xml above*/);
var reader = XmlReader.Create(stream);
var hpCount = 0;
reader.MoveToContent();

while (reader.Read())
{
  if(reader.NodeType == XmlNodeType.Element)
  {
     if(reader.GetAttribute("Name") == "Computer" && reader.GetAttribute("type") == "HP")
     {
        if(hpCount >1)
        {
           reader.Skip();
          continue;
        }
        hpCount++;
     }
  }
}

but the Skip isn't working, next element that got read is

<Accessory type="screen" model="hp"/>

any help of how to skip these lines ? thank you.

Upvotes: 0

Views: 1062

Answers (3)

andy
andy

Reputation: 6079

Instead of checking the hpCount > 1, check hpCount > 0

if(hpCount >1)
{
  reader.Skip();
  continue;
 }

Upvotes: 0

Amicable
Amicable

Reputation: 3101

actually this won't help since I'm gonna filter according to count, sorry I've updated the code up there , could you please re-check it?

List<XElement> query = from c in xdoc.Decendants("Computer") // from <Computer> tag or lower
where (string)c.Attribute("type") == "HP" // where <Computer> attribute name is "type" and "type" equals string value "HP"
select c; // return List of matching `<Computer>` XElements

int HpComputers = query.count; // You want to filter by amount of HP computers?

Filter according to count like this?

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236268

You can easily parse your xml with Linq:

XDocument xdoc = XDocument.Parse(instanceXml);
var query = from c in xdoc.Descendatns("Computer")
            where (string)c.Attribute("type") != "HP"
            select new {
               Name = (string)c.Attribute("Name"),
               Type = (string)c.Attribute("type"),
               Accessories = from a in c.Elements()
                             select new {
                                Type = (string)a.Attribute("type"),
                                Model = (string)a.Attribute("model")
                             }
            };

This will give you collection of strongly-typed anonymous objects, representing computer data with nested collection of accessories.

Upvotes: 1

Related Questions