How can I rewrite this Linq to XML query?
I am preferring LINQ to XML over XMLReader because it feels much easier to use. However, I know I'm doing it wrong somewhere. I'm not looking for faster execution or anything, just a cleaner rewrite. I can't tell if it'll fit cleanly into the from foo in bar where foo is some condition
form, but there's g开发者_运维知识库ot to be a cleaner way.
I am not using anonymous objects here and instead outputting as strings because I am excluding some code which will adapt the data into existing objects - however, it is kind of a messy structure currently which I need to refactor.
My XML looks like this.
<?xml version="1.0" encoding="utf-8" ?>
<entity name="Something">
<Component type="RenderComponent">
<Material type="string">fur</Material>
<Reflectiveness type="int">678</Reflectiveness>
</Component>
<Component type="HealthComponent">
<Sound type="int">60</Sound>
</Component>
</entity>
And my code:
static void Main(string[] args)
{
XDocument xdoc = XDocument.Load(@"..\..\XMLFile1.xml");
List<string> comNames = new List<string>();
Dictionary<string, string> paramValues = new Dictionary<string, string>();
List<string> paramTypes = new List<string>();
foreach (XElement e in xdoc.Root.Elements("Component"))
{
string type = e.Attribute("type").Value;
foreach(XElement param in e.Elements())
{
paramValues.Add(param.Name.LocalName, param.Value);
paramTypes.Add(param.Attributes().First().Value);
}
Console.WriteLine(" \n\n\n");
comNames.Add(type);
}
}
Giving outputs of:
comNames - RenderComponent, HealthComponent
paramValues - (Material, fur), (Reflectiveness, 678), (Sound, 60)
paramTypes - string, int, int
If it clears it up somewhat, the general layout of the file:
- Root node
entity
with aname
attribute (forgot in this example) n
Component nodes withtype
attributes- Each
Component
node has a number of child nodes which have names, atype
attribute, and avalue
.
I think, you can do something like this:
XDocument xdoc = XDocument.Load(@"..\..\XMLFile1.xml");
var data =
xdoc.Root.Elements("Component")
.SelectMany(e => new
{
type = e.Attribute("type").Value,
paramValues = e.Elements()
.Select(x => new KeyValuePair<string,
string>
(x.Name.LocalName,
x.Value)),
paramType = e.Elements()
.Select(x => x.Attributes().First()
.Value)
});
List<string> comNames = data.Select(x => x.type).ToList();
List<string> paramTypes = data.Select(x => x.paramType).ToList();
Dictionary<string, string> paramValues = data.Select(x => x.paramValues)
.ToDictionary(x => x.Key,
x => x.Value);
But honestly, I think your original code is just fine.
精彩评论