我想根据对象中与XML中元素名称相匹配的属性,将XML
字符串的某些元素处理到对象中。
XML
的示例结构如下:
<Bar>
<Body>
<Header>
<A>Value</A>
<B>true</B>
</Header>
<Data>
<D>Value</D>
</Data>
<Data>
<D>Value2</D>
<Data>
</Body>
</Bar>
XML中可能有多个 <Data>
个元素,但<Header>
只存在一次。我设置的课程如下:
public class Foo
{
public string A { get; set; }
public bool B { get; set; }
public List<FooData> { get; set; }
public void ProcessXml(string xml)
{
XDocument xDoc = XDocument.Load(new StringReader(xml));
var propVals = (from ele in xDoc.Descendants()
join prop in this.GetType().GetProperties() on ele.Name.LocalName equals prop.Name
select new
{
prop = prop,
val = new Func<object>(() =>
{
object objValue = null;
prop.PropertyType.TryParse(ele.Value, ref objValue);
return objValue;
}).Invoke()
});
propVals.ToList().ForEach(x => x.prop.SetValue(this, x.val, null));
}
}
public class FooData
{
public string D { get; set; }
}
我提出了开始设置的方法ProcessXml
,但是在我只设置Header
值(A,B)的那一刻,关于如何添加许多的任何想法很容易在同一方法中将FooData
个项目放入List
?
public static class TypeExtensions
{
public static void TryParse(this Type t, object valIn, ref object valOut)
{
//Do some parsing logic
try{
out = TypeDescriptor.GetConverter(t).ConvertFromInvariantString(valIn);
return true;
} catch(Exception) { return false; }
}
}
答案 0 :(得分:1)
我使用与标题内容类似的行,因为没有一种简单的方法可以将它组合成一行。
var dataElements = (from dataDescendants in (from ele2 in xDoc.Descendants()
Where ele2.Name.LocalName == "Data"
select ele2.Descendants())
from dataDescendant in dataDescendants
join prop in typeof(FooItem).GetProperties() on prop.Name equals dataDescendant.Name.LocalName
select Element = dataDescendant, Property = prop, dataDescendants
group by dataDescendants into g = group
select g).ToList();
dataElements.ForEach(dataElement =>
{
FooItem fi = new FooItem();
dataElement.ToList.ForEach(x =>
{
object objVal = null;
x.Property.PropertyType.TryParse(x.Element.Value, objVal);
x.Property.SetValue(fi, objVal, null);
}
DataItems.Add(fi);
}
答案 1 :(得分:0)
如果您的XML非常简单,您可以使用序列化来获取此动态/自加载行为,方法是使用适当的XML Serialization attributes来修饰模型类,但每个缩进级别至少需要1个类在文件中:
void Main()
{
var xml = @"<Bar>
<Body>
<Header>
<A>Value</A>
<B>true</B>
</Header>
<Data>
<D>Value</D>
</Data>
<Data>
<D>Value2</D>
</Data>
</Body>
</Bar>";
var serializer = new XmlSerializer(typeof(Bar));
serializer.Deserialize( new MemoryStream( Encoding.ASCII.GetBytes( xml ) ) ).Dump();
}
public class Bar
{
public Body Body { get; set; }
}
public class Body
{
public Header Header { get; set; }
[XmlElement]
public Data[] Data { get; set; }
}
public class Header
{
public string A { get; set; }
public string B { get; set; }
}
public class Data
{
public string D { get; set; }
}
(已编辑:我错过了只有1个标头元素)