- Home /
convert xml into array?
Is there any library that will help convert xml into an array where each tag would be converted into an array item.
<entry>
<tagA>1</tagA>
<tagB>A</tagB>
</entry>
<entry>
<tagA>2</tagA>
<tagB>B</tagB>
</entry>
would be convereted into arrayA=[1,2] arrayB=["A","B"]
Answer by whydoidoit · May 21, 2012 at 10:17 PM
Sure, with one caveat - you need a single root element in your XmlDocument to use System.Xml.
So add the following usings:
using System.Linq;
using System.Xml;
using System.Collections.Generic;
This routine will give you a dictionary with the keys tagA and tagB (and any others you define), the dictionary lookup is an array of the values - please note that they are all text - you can convert text values to numbers using int.Parse() and float.Parse()
var str = @"<root><entry><tagA>1</tagA><tagB>A</tagB></entry><entry><tagA>2</tagA><tagB>B</tagB></entry></root>";
var doc = new XmlDocument();
doc.LoadXml(str);
var lookup = doc.DocumentElement
.ChildNodes.OfType<XmlNode>()
.SelectMany(c => c.ChildNodes.OfType<XmlNode>())
.GroupBy(n => n.Name, (k,l) => new { tag = k, items = l.Select(t => t.InnerText).ToArray()})
.ToDictionary(tag => tag.tag, tag => tag.items);
See how I've added a root element? You need that.
Now you have an array collection you can access like this:
var myTagAArray = lookup["tagA"];
Or you could loop through the keys, values or keys and values using a foreach().
UPDATE:
Here is a JavaScript version:
import System.Xml;
import System.Linq;
import System.Collections.Generic;
...
var str = "<root><entry><tagA>1</tagA><tagB>A</tagB></entry><entry><tagA>2</tagA><tagB>B</tagB></entry></root>";
var doc = new XmlDocument();
doc.LoadXml(str);
var lookup = doc.DocumentElement
.ChildNodes.OfType.<XmlNode>()
.SelectMany(
function(c) {
return c.ChildNodes.OfType.<XmlNode>();
}
).GroupBy(function(n) {
return n.Name;
}).Select(function(g) {
return { "tag": g.Key,
"values": g.Select(function(n){ return n.InnerText;}).ToArray() };
}).ToDictionary(function(h) { return h["tag"];} );
var myTagAArray = lookup["tagA"]["values"];
var myTagBArray = lookup["tagB"]["values"];
Note: due to a Unity bug you have to use the second ["values"] dereference to get the array. Unity emits invalid code if you try to use the normal method that the c# version does to remove this added syntactic annoyance. For those who are interested I'll post an explanation of the LINQ in the comments
Yes. I'm working in javascript. I can translate simple c# but I've never seen anything like the last 4 lines before, could someone help me rewrite it in javascript? The application is to retrieve a list of movies from youtube which comes back as xml. So It already has a root. This would be great if it works thanks $$anonymous$$ike for posting this.
Explanation of the JS version:
var doc = new XmlDocument();
doc.LoadXml(str);
//So firstly we want the child nodes of the body of the X$$anonymous$$L document
var lookup = doc.DocumentElement
//Use LINQ to ensure we only get XmlNodes
.ChildNodes.OfType.<XmlNode>()
//Select many is going to get all of the children of each of the
//top level XmlNodes in ChildNodes and turn them all into one
//long list (all of the child nodes from each grouped together)
//In this case these are the first level <entry> elements
//and we get the tagA and tagB element children in this function
.Select$$anonymous$$any(
function(c /* This is the entry element */) {
//Now we get all of the children, these are the tagA and tagB
return c.ChildNodes.OfType.<XmlNode>();
}
)
//Now we need to group them into tagA and tagB (and of course any
//other groups if they existed) we do this using GroupBy
.GroupBy(function(n /* This is the tagA or tagB */) {
//Group it on the tag name
return n.Name;
})
//By this point our collection now contains an inner Linq
//grouping object that has a $$anonymous$$ey and is itself an iterator
//of the XmlNodes in the group. Our $$anonymous$$ey will be tagA or tagB
//as selected in the GroupBy function we supplied.
//We are going to turn this into something that we can use
//to get out the values as an array. In javascripts case
//this is going to be a boo hash. c# would actually have
//an anonymous class here
.Select(function(g /* The grouping object (see above)*/) {
//Create a value to hold the key
return { "tag": g.$$anonymous$$ey ,
"values":
//Now we want an array of the tag values
//So we convert the XmlNodes in the iterator
//to the text version
g.Select(function(n /* Each XmlNode in the group */){
//Get the text of the XmlNode
return n.InnerText;
})
//Convert it to an array
.ToArray() };
})
//Right so now our collection contains our boo hashes
//with their "tag" and "values" array. We need some
//way to easily get to it using a lookup on the tag
//name - that would be a dictionary.
//In c# we would use the two parameter version of
//ToDictionary to make they key be the "tag" and the
//items inside that key be the "values" array - but
//the JS compiler emits invalid code for the two
//parameter version. So we are using the single
//parameter version that creates a dictionary
//keyed by the return value of the function
//and containing the boo hash.
.ToDictionary(
//This function returns what will be the key
//of the dictionary
function(h /* This is going to be each of the boo hashes*/) {
//Return the tag name
return h["tag"];
}
);
//We can get a value from the dictionary using the tag name,
//in this case the return of that will be the boo hash. We therefore
//need to dereference the values
var g = lookup["tagA"]["values"];
Answer by kolban · May 21, 2012 at 10:13 PM
I am not aware of a specific library that will turn each "tag" (an XML Element) into an array item but you can construct something similar yourself. Since Unity leverages Mono and Mono is an implementation of .NET, there are classes for working with XML supplied in the System.XML package... see:
http://docs.mono-android.net/?link=N%3aSystem.Xml
Using these classes, you can parse and walk the XML document as a DOM tree and determine all the entries contained within.
Your answer
Follow this Question
Related Questions
C#-XMLSerialize a Struct with Vector3 Array in it 2 Answers
Does XML Serialization Support "Class Object" Arrays? 1 Answer
create string array from xml 2 Answers
Parsing XML - appropriate array size 3 Answers
XML File, or Array? 1 Answer