简体   繁体   中英

Unity XML Get list values from xml list to c# list

I need to retrieve list values from attributes in a file with this XML:

<LISTS>
<LIST list="213 82 14 2 3 4 18 4 1 5 5 3 6 5 2"/>
<LIST list="2 4 5 1 4 0 0 0 2 3 5 532 7 10 0"/>
<LIST list="10 511 4 8 2 6 4 721 2 5 7 10 10 4"/>
</LISTS>

Using a stream reader I put the XML in a string inside a list. So it looks like this:

 <LISTS><LIST list="213 82 14 2 3 4 18 4 1 5 5 3 6 5 2"/><LIST list="2 4 5 1 4 0 0 0 2 3 5 532 7 10 0"/><LIST list="10 511 4 8 2 6 4 721 2 5 7 10 10 4"/></LISTS>

Then I create the XML document

Xmldoc = new XmlDocument();
Xmldoc.LoadXml(XmlLineList[0]) //i get an obj reference not set to instance of obj ex here. Even tho i can see in the inspector the xml line is there.

If I use

Xmldoc.Load(XmlLineList[0]) // Illegal characters in Path

And that is as far as I have gone. I have been reading documentation all night but cant find a good answer or a case that resembles mine. Need to pass the elements of the xml list into a c# list. Every list in a different one, so three lists.

Your XML basically consists of a sequence <LIST> of lists list="1 2 3" of integers. You have a couple options to parse this XML and extract a List<int> list for each <LIST> element.

Firstly, You can use XmlSerializer to deserialize your XML. First define the followng data model:

[XmlRoot("LISTS")]
public class ListRoot
{
    [XmlElement("LIST")]
    public List<ListEntry> Lists { get; set; } = new List<ListEntry>();
}

public class ListEntry
{
    [XmlAttribute("list")]
    public List<int> ListItems { get; set; } = new List<int>();
}

Then you can deserialize from a file located at fileName as follows:

ListRoot listRoot;
var serializer = new XmlSerializer(typeof(ListRoot));
using (var stream = File.OpenRead(fileName))
    listRoot = (ListRoot)serializer.Deserialize(stream);

By marking the List<int> ListItems with [XmlAttribute("list")] , XmlSerializer will automatically deserialize the space-delimited list="2 4..." attributes into the inner ListItems list.

Now you can access the list items as follows:

foreach (var entry in listRoot.Lists)
{
    List<int> list = entry.ListItems; // The contents of each list="1 2 ..." /> attribute materialized as a List<int>
    // Process the List<int> list however you want:
    Console.WriteLine(string.Join(",", list));
}

Which outputs:

213,82,14,2,3,4,18,4,1,5,5,3,6,5,2
2,4,5,1,4,0,0,0,2,3,5,532,7,10,0
10,511,4,8,2,6,4,721,2,5,7,10,10,4

Demo fiddle #1 here .

Alternatively, you could use LINQ to XML to load your XML into an XDocument and query it using LINQ :

var listRoot = XDocument.Load(fileName);

var listItems = listRoot.Root
    .Elements("LIST") // Select the <LIST> child nodes
    .Select(e => e.Attribute("list")) // Select the list=".." attribute
    .Select(a => a.Value.Split(' ').Select(s => XmlConvert.ToInt32(s)).ToList()) // Convert the space-delimited integer string to a list of integers
    .ToList(); // And materialize the query

foreach (List<int> list in listItems)
{
    // Process the List<int> list however you want:
    Console.WriteLine(string.Join(",", list));
}

Demo fiddle #2 here .

I don't really recommend using the older XmlDocument for new code as LINQ to XML is easier to use and more performant.

It is better to use LINQ to XML API. It is available in the.Net Framework since 2007.

Here is your starting point.

c#

void Main()
{
    const string fileName = @"e:\temp\input.xml";
    // Load XML file directly from the file system
    //XDocument xdoc = XDocument.Load(fileName);
    
    XDocument xdoc = XDocument.Parse(@"<LISTS>
            <LIST list='213 82 14 2 3 4 18 4 1 5 5 3 6 5 2'/>
            <LIST list='2 4 5 1 4 0 0 0 2 3 5 532 7 10 0'/>
            <LIST list='10 511 4 8 2 6 4 721 2 5 7 10 10 4'/>
        </LISTS>
        ");
            
    foreach (XElement xelem in xdoc.Descendants("LIST"))
    {
        Console.WriteLine("list: '{0}'", xelem.Attribute("list").Value);
    }
}

Output

list: '213 82 14 2 3 4 18 4 1 5 5 3 6 5 2'
list: '2 4 5 1 4 0 0 0 2 3 5 532 7 10 0'
list: '10 511 4 8 2 6 4 721 2 5 7 10 10 4'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM