XmlReader How to read properly?

430 Views Asked by At

what is the best way to read xml like this one:

<Users>
<user name = "mail">
    <supplier name = "supp1">
        <project name = "proj1">
            <subscribe name= "sub1"/>
            <subscribe name = "sub2"/>
        </project>
    </supplier>
    <supplier name = "supp2">
        <project name = "proj2">
            <subscribe name = "sub3"/>
        </project>
        <project name = "proj3">
            <subscribe name= "sub4"/>
            <subscribe name = "sub5"/>
        </project>
        <project name = "proj4"/>
    </supplier>
    <supplier name = "supp3"/>
            <supplier name = "supp5">
                 <project name = "proj4"/>
    <supplier name = "supp4"/>
</user>
</Users>

For now I am using

 While(reader.Read())
 {
    if (((reader.NodeType == XmlNodeType.EndElement) && (reader.Name == "user")))
     break;

            if ((reader.NodeType == XmlNodeType.Element) && (reader.Name =="supplier"))
            {
                foreach (TreeNode tree in TreeView1.Nodes)
                {
                    if (reader.GetAttribute(0) == tree.Text)
                    {
                        TreeView1.SelectedNode = tree;
                        TreeView1.SelectedNode.Checked = true;

                        Get_projects(reader, tree);

                        break;
                    }
                }
            }
}

this is the main after that is get_projects(...):

private void Get_projects(XmlReader reader, TreeNode tree)
    {
        while (reader.Read())
        {
            if ((reader.NodeType == XmlNodeType.EndElement) && (reader.Name ==  "supplier")) break;
                //(reader.IsEmptyElement && reader.Name == "supplier")
            if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "project"))
            {
                foreach (TreeNode projTree in tree.Nodes)
                {
                    if (reader.GetAttribute(0) == projTree.Text)
                    {
                        TreeView1.SelectedNode = projTree;
                        TreeView1.SelectedNode.Checked = true;

                        Get_subscribes(reader, projTree);
                        break;
                    }
                }
            }
        }
    }

the Get_subscribes(reader, projTree):

private void Get_subscribes(XmlReader reader, TreeNode tree)
    {
        while (reader.Read())
        {
             if ((reader.NodeType == XmlNodeType.EndElement) && (reader.Name ==   "project") ||
                (reader.IsEmptyElement && reader.Name == "project")) break;
            if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "subscribe"))
            {
                foreach (TreeNode subTree in tree.Nodes)
                {
                    if (reader.GetAttribute(0) == subTree.Text)
                    {
                        TreeView1.SelectedNode = subTree;
                        TreeView1.SelectedNode.Checked = true;

                        break;
                    }
                }
            }
        }
    }

It doesn't work, so I am wondering is there a better way or what am i missing?

3

There are 3 best solutions below

0
On

you can try XPath to read informations you need

XMLDocument doc = new XMLDocument();
doc.Load(your_xml_file_path);
XMLNodeList list = doc.SelectNodes(@"//project"); //get all project element
0
On

I will give you sample to read properly

<ApplicationPool>
    <Accounts>
        <Account>
            <NameOfKin></NameOfKin>
            <StatementsAvailable>
                <Statement></Statement>
            </StatementsAvailable>
        </Account>
    </Accounts>
</ApplicationPool>

static IEnumerable<XElement> SimpleStreamAxis(string inputUrl,                                          string elementName)
{
  using (XmlReader reader = XmlReader.Create(inputUrl))
  {
    reader.MoveToContent();
    while (reader.Read())
    {
      if (reader.NodeType == XmlNodeType.Element)
      {
        if (reader.Name == elementName)
        {
          XElement el = XNode.ReadFrom(reader) as XElement;
          if (el != null)
          {
            yield return el;
          }
        }
      }
    }
  }
}


using (XmlReader reader = XmlReader.Create(inputUrl))
{
    reader.ReadStartElement("theRootElement");

    while (reader.Name == "TheNodeIWant")
    {
        XElement el = (XElement) XNode.ReadFrom(reader);
    }

    reader.ReadEndElement();
}

Source: Reading Xml with XmlReader in C#

Hope this help.

0
On

I would consider the reverse approach i.e.: instead of reading XML and checking if a node exists in TreeView I would prefer to use XPath to check if a node exists in XML document.

In order to do so you have to traverse TreeView nodes and for each node build XPath query

e.g.: /Users/user/supplier[@name='supp1']/project[@name='proj1'].

Having XPath query you can create an instance of XPathDocument based on your XMLReader and run the query. If something is found, you will check current node in TreeView.