.NET 4.0中是否提供支持DLR的XML导航和阅读课程?例如,假设我有这个XML:
<foo>
<bar>foobar is here</bar>
<bar>foobar is also here</bar>
<baz>foobar is not here</bar>
</foo>
是否有一种简单的方法可以像这样导航这个XML:
var doc = SomeDlrEnabledParser.Parse (xmlString);
foreach (var node in doc.foo.bar)
{
if (node == "foobar is here")
DoSomething();
else
DoSomethingElse();
}
我可以看到很多原因导致上述方法存在问题,包括名称空间,属性与元素,区分集合与单个元素,编码XML与文本等。
但我处理的大部分XML都是非常简单和只读的,而且我愿意接受合理的默认行为来换取避免使用简单XML的“括号和引用汤”的特点。 4.0之前的世界。
例如,“dot”运算符可以检查子元素名称之前的属性名称。或者非收集操作会自动应用于第一个元素(就像jQuery一样)。
.NET 4.0 Framework类库是否包含这样的内容?如果没有,建议一个好的开源项目或支持DLR的XML库的样本?
答案 0 :(得分:2)
我做了一点测试:
public class DynamicXml : DynamicObject, IEnumerable<XNode>
{
private readonly IEnumerable<XNode> nodes;
public DynamicXml(params XNode[] nodes)
{
this.nodes = nodes;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var children = nodes.OfType<XContainer>().SelectMany(node => node.Elements(binder.Name)).Cast<XNode>().ToArray();
result = new DynamicXml(children);
return true;
}
public IEnumerator<XNode> GetEnumerator()
{
return nodes.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
例如:
class Program
{
static void Main(string[] args)
{
dynamic dynDoc = new DynamicXml(XDocument.Parse(
@"<foo>
<bar>foobar is here</bar>
<bar>foobar is also here</bar>
<baz>foobar is not here</baz>
</foo>"));
foreach (XElement node in dynDoc.foo.bar)
{
if (node.Value == "foobar is here")
Console.WriteLine("found: {0}", node);
else
Console.WriteLine("not found: {0}", node);
}
Console.ReadKey(true);
}
}
然而,这个和其他代码之间的界面似乎并不那么好。
例如,如果我们想对节点使用Linq,我们必须首先显式地转换为IEnumerable
...否则我们的Where
将被解释为元素名称。
((DynamicXml)dynXml.foo.bar).Where(x => x.Value == "foobar is here");
您可以直接在动态类型上实现Where
,但您必须对所有lambdas进行限定:
foo.bar.Where((Func<XElement,bool>)(x => x.Value == "foobar is here"))
那就是说,如果您只是从这样的XML树中提取值,我认为它可以正常工作。