Jav*_*aSa 2 c# xml linq reflection linq-to-xml
我是linq to Xml的新手.
我有一个递归方法,它获取as参数XElement root,该方法应该以某种方式保存XML数据,它将表示给定递归深度的相关子树根.
void recursiveMethod(XElement root);
更具体地说,还要看一下这个XML示例:
<start>
<Class>
<Worker>
<Name> Dan </Name>
<Phone> 123 </Phone>
<Class>
<Address>
<Street> yellow brick road </Street>
<Zip Code> 123456 </Zip Code>
</Address>
</Class>
</Worker>
</Class>
...
</start>
Run Code Online (Sandbox Code Playgroud)
您可以想象,Name是值类型,Address而是类引用.
应通过反射动态添加Xml信息(自顶向下方法).
总而言之,想象一下,我正在调查WorkerClass并达到AddressClass并希望"向下钻取",所以我想用当前Worker类的子节点的正确引用来调用我的递归方法作为新的XElement根,所以我将能够添加我在Address下面的一级递归深度中通过反射找到的内容.
请注意,此引用应为XElement类型.
我怎样才能做到这一点?
编辑:如果你有另一个想法做所有这些,但不是XElement我也会很高兴听到,虽然我更喜欢它与XElement参数.
另一个问题:
我已经开始以一种天真的方式实现它,比如遍历所有字段(FieldInfo []的变量),如果我遇到了值类型(IsValueType),我就是这样做的
root.Add(new XElement("Field",
new XElement("Type", ...),
new XElement("Variable Name", ...),
new XElement("Value", ...)));
Run Code Online (Sandbox Code Playgroud)
所以,只是为了一般知识:
1.有没有办法只获得一个节点的引用到它的后代,所以在较低的递归级别,我将能够做另一个root.Add(...),但如上所述这个root将是对以前root的孩子的引用?(这意味着在没有Linq语法的情况下进行整个操作)
2.我设法通过反射获得私有字段的价值,而无需使用属性,是否有问题?我应该总是通过反射中的属性来获取值吗?
此扩展方法将以所需格式构建XElement:
public static class Extensions
{
public static XElement ToXml<T>(this T obj)
{
Type type = typeof(T);
return new XElement("Class",
new XElement(type.Name,
from pi in type.GetProperties()
where !pi.GetIndexParameters().Any()
let value = (dynamic)pi.GetValue(obj, null)
select pi.PropertyType.IsPrimitive ||
pi.PropertyType == typeof(string) ?
new XElement(pi.Name, value) :
Extensions.ToXml(value)
)
);
}
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么:
dynamic对象.这很重要,否则属性值类型将object在ToXml<T>方法的递归调用期间被推断.用法:
Worker worker = new Worker()
{
Name = "Serge",
Phone = "911",
Address = new Address() { Street = "Elm street", ZipCode = 666 }
};
XElement xml = worker.ToXml();
Run Code Online (Sandbox Code Playgroud)
结果:
<Class>
<Worker>
<Name>Serge</Name>
<Phone>911</Phone>
<Class>
<Address>
<Street>Elm street</Street>
<ZipCode>666</ZipCode>
</Address>
</Class>
</Worker>
</Class>
Run Code Online (Sandbox Code Playgroud)
但是 当两个对象相互引用时应该小心(在这种情况下会发生无限递归)
在这种情况下,您可以使用类似字典或散列集的内容来存储xml中已存在的所有对象:
Type type = obj.GetType();
if (set.Contains(obj))
return new XElement("Class", new XAttribute("name", type.Name));
set.Add(obj);
return new XElement("Class", ...);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2643 次 |
| 最近记录: |