Linq to Xml 值对
Linq to Xml Value Pair
我有 Xml 看起来像...
<root>
<extension>
<Obj>
<Id>12345</Id>
<NameValuePair>
<Name>Prop1</Name>
<Value>Value1</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop2</Name>
<Value>Value2</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop3</Name>
<Value>Value3</Value>
</NameValuePair>
</Obj>
<Obj>
<Id>67890</Id>
<NameValuePair>
<Name>Prop4</Name>
<Value>Value5</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop5</Name>
<Value>Value5</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop6</Name>
<Value>Value6</Value>
</NameValuePair>
</Obj>
</extension>
</root>
我正在尝试使用 XDocument / Linq 来 XML 来实现..
Id: 12345
Prop1: Value1
Prop2: Value2
Prop3: Value3
Id: 67890
Prop1: Value1
Prop2: Value2
Prop3: Value3
我已经知道需要查找的 ID,在此处的代码中,我已按照示例将其硬编码为“12345”...这就是我目前所拥有的...
var val = xmlDoc.Element("extension").Elements("Obj")
.Where(i => (string)i.Element("Id") == "12345" &&
(string)i.Element("NameValuePair").Element("Name") == "Prop2")
.Select(i => (string)i.Element("NameValuePair").Element("Value")).FirstOrDefault();
似乎正在发生的事情是每次我 "try" 得到一个值...它只是 returns NULL..
最终,我试图将它放入一个对象中,例如...
internal class MyClass
{
public string Id { get; internal set; }
public string Prop1 { get; internal set; }
public string Prop2 { get; internal set; }
public string Prop3 { get; internal set; }
}
有什么建议吗?
在 class 中使用字典而不是属性。我用 xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication74
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<MyClass> myClasses = doc.Descendants("Obj").Select(x => new MyClass() {
Id = (int)x.Element("Id"),
dict1 = x.Elements("NameValuePair").GroupBy(y => (string)y.Element("Name"), z => (string)z.Element("Value"))
.ToDictionary(y => y.Key, z => z.FirstOrDefault()),
dict2 = x.Elements("NameValuePair").GroupBy(y => (string)y.Element("Name"), z => (string)z.Element("Value"))
.ToDictionary(y => y.Key, z => z.ToList())
}).ToList();
}
}
internal class MyClass
{
public int Id { get; internal set; }
public Dictionary<string,string> dict1 { get; set; }
public Dictionary<string, List<string>> dict2 { get; set; }
}
}
如果对于同一个 Prop
你有多个 Value
,你可以将你的值转换为 Lookup
// use temporary variable to increase performance of item.Element, I'm not sure that all 'Obj' element contains 'Id'
XElement idElement = null;
var values = doc.Descendants("Obj")
.Where(item => (idElement = item.Element("Id")) != null && idElement.Value == "12345")
.Descendants("NameValuePair")
.ToLookup(o => o.Element("Name").Value, o => new { Id = idElement.Value, Value = o.Element("Value").Value });
foreach (var valuesByProp in values)
{
foreach (var prop in valuesByProp)
{
Console.WriteLine($"{prop.Id}, {valuesByProp.Key}, {prop.Value}");
}
}
或者您可以直接将所有 NameValuePair
按 Id
分组,然后按 Prop
分组
var values = doc.Descendants("Obj")
.ToLookup(o => o.Element("Id").Value,
o => o.Descendants("NameValuePair").ToLookup(p => p.Element("Name").Value, p => p.Element("Value").Value));
foreach (var groupById in values)
{
foreach (var groupByProp in groupById)
{
foreach (var valuesByProp in groupByProp)
{
foreach (var value in valuesByProp)
{
Console.WriteLine($"{groupById.Key}, {valuesByProp.Key}, {value}");
}
}
}
}
我有 Xml 看起来像...
<root>
<extension>
<Obj>
<Id>12345</Id>
<NameValuePair>
<Name>Prop1</Name>
<Value>Value1</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop2</Name>
<Value>Value2</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop3</Name>
<Value>Value3</Value>
</NameValuePair>
</Obj>
<Obj>
<Id>67890</Id>
<NameValuePair>
<Name>Prop4</Name>
<Value>Value5</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop5</Name>
<Value>Value5</Value>
</NameValuePair>
<NameValuePair>
<Name>Prop6</Name>
<Value>Value6</Value>
</NameValuePair>
</Obj>
</extension>
</root>
我正在尝试使用 XDocument / Linq 来 XML 来实现..
Id: 12345
Prop1: Value1
Prop2: Value2
Prop3: Value3
Id: 67890
Prop1: Value1
Prop2: Value2
Prop3: Value3
我已经知道需要查找的 ID,在此处的代码中,我已按照示例将其硬编码为“12345”...这就是我目前所拥有的...
var val = xmlDoc.Element("extension").Elements("Obj")
.Where(i => (string)i.Element("Id") == "12345" &&
(string)i.Element("NameValuePair").Element("Name") == "Prop2")
.Select(i => (string)i.Element("NameValuePair").Element("Value")).FirstOrDefault();
似乎正在发生的事情是每次我 "try" 得到一个值...它只是 returns NULL..
最终,我试图将它放入一个对象中,例如...
internal class MyClass
{
public string Id { get; internal set; }
public string Prop1 { get; internal set; }
public string Prop2 { get; internal set; }
public string Prop3 { get; internal set; }
}
有什么建议吗?
在 class 中使用字典而不是属性。我用 xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication74
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<MyClass> myClasses = doc.Descendants("Obj").Select(x => new MyClass() {
Id = (int)x.Element("Id"),
dict1 = x.Elements("NameValuePair").GroupBy(y => (string)y.Element("Name"), z => (string)z.Element("Value"))
.ToDictionary(y => y.Key, z => z.FirstOrDefault()),
dict2 = x.Elements("NameValuePair").GroupBy(y => (string)y.Element("Name"), z => (string)z.Element("Value"))
.ToDictionary(y => y.Key, z => z.ToList())
}).ToList();
}
}
internal class MyClass
{
public int Id { get; internal set; }
public Dictionary<string,string> dict1 { get; set; }
public Dictionary<string, List<string>> dict2 { get; set; }
}
}
如果对于同一个 Prop
你有多个 Value
Lookup
// use temporary variable to increase performance of item.Element, I'm not sure that all 'Obj' element contains 'Id'
XElement idElement = null;
var values = doc.Descendants("Obj")
.Where(item => (idElement = item.Element("Id")) != null && idElement.Value == "12345")
.Descendants("NameValuePair")
.ToLookup(o => o.Element("Name").Value, o => new { Id = idElement.Value, Value = o.Element("Value").Value });
foreach (var valuesByProp in values)
{
foreach (var prop in valuesByProp)
{
Console.WriteLine($"{prop.Id}, {valuesByProp.Key}, {prop.Value}");
}
}
或者您可以直接将所有 NameValuePair
按 Id
分组,然后按 Prop
var values = doc.Descendants("Obj")
.ToLookup(o => o.Element("Id").Value,
o => o.Descendants("NameValuePair").ToLookup(p => p.Element("Name").Value, p => p.Element("Value").Value));
foreach (var groupById in values)
{
foreach (var groupByProp in groupById)
{
foreach (var valuesByProp in groupByProp)
{
foreach (var value in valuesByProp)
{
Console.WriteLine($"{groupById.Key}, {valuesByProp.Key}, {value}");
}
}
}
}