1

This is how the XML file could look:

<data>
  <subdata>
    <datatype id="1" name="data1">
    <xdim>2</xdim>
    <ydim>1</ydim>
    </datatype>
    <datatype id="2" name="data2">
    <xdim>3</xdim>
    <ydim>4</ydim>
    </datatype>
  </subdata>
</data>

Now, i want the following:

  • A list(string) with all datatype id's like "1" & "2" in the preview above
  • A list(string) with all the < xdim > stuff like "2" & "3" above
  • A list(string) with all the < ydim > stuff like "1" & "4" above

Are there easy methods built in in C# for stuff like this? Or could anyone help me with this question?

  • Jonas
2
  • Hi. You could create a List<String> variable and then add each relevant value into it. By the end you have all your values in the list. Commented Mar 10, 2016 at 14:27
  • XLinq is your friend - System.Xml.Linq Commented Mar 10, 2016 at 15:48

6 Answers 6

5

You can use Descendents method.
This method reads all the child nodes even the nested ones where node name matches with specified string.

  var Idstring = MyXml.Descendants("datatype").Select (x=>x.Attribute("Id")).ToList();

    var xdimstring = MyXml.Descendants("xdim").Select (x=>x.Value).ToList();

    var ydimstring = MyXml.Descendants("ydim").Select (x=>x.Value).ToList();

To Appease your curiosity :) This how you can get nodes from specifically subdata node.

var Idstring = MyXml.Descendants("Subdata").Descendants("datatype").Select (x=>x.Attribute("Id")).ToList();

    var xdimstring = MyXml.Descendants("Subdata").Descendants("xdim").Select (x=>x.Value).ToList();

    var ydimstring = MyXml.Descendants("Subdata").Descendants("ydim").Select (x=>x.Value).ToList();

Now let say you have Multiple subdata and you want to read nodes only from first one...Simply use First linq extension method

var Idstring = MyXml.Descendants("Subdata").First().Descendants("datatype").Select (x=>x.Attribute("Id")).ToList();
Sign up to request clarification or add additional context in comments.

4 Comments

Can i add something like "Data must be between < subdata > ... < /subdata >
so you have xdim,ydim node outside of Subdata node also? n you want only ones which are child nodes of Subdata? @JonasAnon
Actually no, but i'm just interested haha
@JonasAnon Check update..I understand the curiosity :)...Well that's how you learn....
4

This works and is fairly neat and simple:

string xml = 
@"<data>
<subdata>
    <datatype id=""1"" name=""data1"">
    <xdim>2</xdim>
    <ydim>1</ydim>
    </datatype>
    <datatype id=""2"" name=""data2"">
    <xdim>3</xdim>
    <ydim>4</ydim>
    </datatype>
</subdata>
</data>";

var xelem = XElement.Parse(xml);

var allIDs = xelem
    .Descendants()
    .Where (x => x.Attribute("id") != null)
    .Select (x => x.Attribute("id").Value)
    .ToList();

var allXdims = xelem
    .XPathSelectElements("//xdim")
    .Select (x => x.Value)
    .ToList();

var allYdims = xelem
    .XPathSelectElements("//ydim")
    .Select (x => x.Value)
    .ToList();

Obviously the part at the start is just getting the XML into an XElement. You might want to do this with:

var xelem = XElement.Load(myXmlLocation);

instead.

Comments

3

The easiest way to convert classes to and from XML in C# is XML Serialization

For your example, you could create a class with member variables corresponding to the tags in your XML. When you want to create your XML file, you serialize the class to an XML File.

When your want to read back the information, you deserialize the contents of the XML file back to the class you created.

Here's a more comprehensive article: https://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx

Comments

1

You can use:

XDocument doc = XDocument.Load(@"..\myfile.xml");

to load your file in a XDocument object.

Then use XDocument methods to create string lists of the required id values:

var ids = (from a in doc.Descendants("subdata").Elements().Attributes("id")
           select a.Value).ToList();

var xids = (from e in doc.Descendants("datatype").Elements("xdim")
            select e.Value).ToList();

var yids = (from e in doc.Descendants("datatype").Elements("ydim")
            select e.Value).ToList();

Comments

1
        var xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(
            "<data><subdata><datatype id=\"1\" name=\"data1\"><xdim>2</xdim><ydim>1</ydim></datatype><datatype id=\"2\" name=\"data2\"><xdim>3</xdim><ydim>4</ydim></datatype></subdata></data>");
        var nodes = xmlDocument.SelectNodes("//datatype");
        var first = new List<string>();
        var Second = new List<string>();
        var third = new List<string>();
        foreach (XmlNode node in nodes)
        {
            first.Add(node.Attributes["id"].Value);
        }
        nodes = xmlDocument.SelectNodes("//xdim");
        foreach (XmlNode node in nodes)
        {
            Second.Add(node.InnerText);
        }
        nodes = xmlDocument.SelectNodes("//ydim");
        foreach (XmlNode node in nodes)
        {
            third.Add(node.InnerText);
        }

1 Comment

This seems to create one long string that looks like this: "122314".
0

Try something like this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication81
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<data>" +
                  "<subdata>" +
                    "<datatype id=\"1\" name=\"data1\">" +
                    "<xdim>2</xdim>" +
                    "<ydim>1</ydim>" +
                    "</datatype>" +
                    "<datatype id=\"2\" name=\"data2\">" +
                    "<xdim>3</xdim>" +
                    "<ydim>4</ydim>" +
                    "</datatype>" +
                  "</subdata>" +
                "</data>";

            XElement data = XElement.Parse(xml);
            var results = data.Descendants("subdata").Elements()
                .GroupBy(x => x.Name.LocalName)
                .Select(x => new
                {
                    name = x.Key,
                    value = x.Select(y => (string)y).ToList(),
                    attributes = x.Attributes()
                       .Select(y => new {name = y.Name.LocalName, y.Value})
                       .GroupBy(y => y.name, z => z.Value)
                       .ToDictionary(y => y.Key, z => z.ToList())
                }).ToList();

        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.