为什么不是';NET 4中的XMLT动态文档?

为什么不是';NET 4中的XMLT动态文档?,xml,dynamic,c#-4.0,Xml,Dynamic,C# 4.0,我希望看到使用dynamic的一个领域是XML。我认为这将使XML处理代码的编写更加简单,我相信在C#4问世之前,我已经看到了一些关于这方面的例子,并且提到了这一特性的用途之一 因此,我的问题是:为什么XmlDocument(或XDocument)没有动态化,或者为什么在C#4中没有用于动态XML操作的新类 这对我来说更奇怪,当我在PosiS壳中考虑代码 /Copy>。 最有可能的是他们没有想到过,而且程序员通常不乐意把动态放在一个地方:动态是一个定时炸弹。在编译时尽可能多地捕获…因为XmlDo

我希望看到使用
dynamic
的一个领域是XML。我认为这将使XML处理代码的编写更加简单,我相信在C#4问世之前,我已经看到了一些关于这方面的例子,并且提到了这一特性的用途之一

因此,我的问题是:为什么
XmlDocument
(或
XDocument
)没有动态化,或者为什么在C#4中没有用于动态XML操作的新类


这对我来说更奇怪,当我在PosiS壳中考虑代码是动态的,代码如<代码> $XMLDOC .Roo.SubNo.Sub节点> /Copy>。

最有可能的是他们没有想到过,而且程序员通常不乐意把动态放在一个地方:动态是一个定时炸弹。在编译时尽可能多地捕获…

因为XmlDocument早于泛型,修复它会破坏旧代码


另外,XmlDocument被列为半过时的。

给出一些评论,让我提供另一个答案。最初的问题是为什么XmlDocument在.NET4中不是动态的。虽然可以通过
IDynamicMetaObjectProvider
将“expando”属性功能添加到现有的xml文档类中,但这样做可能是一项不平凡的工作。要使System.Xml中的原始Xml对象模型完全动态,需要对Xml框架进行一些广泛的修改,并且需要将IDynamicMetaObjectProvider添加到所涉及的每个对象中。这包括XmlDocument、XmlElement、XmlAttribute、XmlNode和所有其他xml内容类型,如注释、文本节点等。此外,还需要修改元素、属性和值的查找和处理中涉及的大量支持基础结构、内部类型等(打开Reflector,看看System.Xml……一半以上的类型是内部类型,它们彼此之间以及可用的公共类型之间高度相互依赖。)

同样重要的是考虑在.NET中实现XML的Expand属性的适当范围。您将只在XML文档和相关类型中停止吗?还是更合适地包括XPath、XML Schema等?


回答最初的问题,“为什么.NET4中的XmlDocument不是动态的?”,我认为简单的答案是:实现完全“动态”的API,或者在这里的Xml中,提供任意Xml文档属性扩展的API远不是一项简单的任务。考虑到Microsoft的工作道德,如果他们试图实现expando属性,他们不会轻易完成这样的任务是合乎逻辑的对于Xml框架,我希望并期望它能像.NET的其他部分一样,得到同样程度的仔细关注和关注。

我对如此多看似权威的讨论而没有答案感到惊讶。你的问题太棒了。它正好解决了
dynamic
关键字所涉及的令人敬畏的事情问题是,并不是很多人真正知道如何充分利用它

虽然MS没有为我们构建动态XML对象,但他们确实为我们提供了工具,让我们自己使用该类来实现

public class DynamicXmlElement : DynamicObject {
   XmlElement _xmlEl;

   public DynamicXmlElement(string xml) {
      var xmldoc = new XmlDocument();
      xmldoc.LoadXml(xml);
      _xmlEl = xmldoc.DocumentElement;
   }

   public DynamicXmlElement(XmlElement el) {
      _xmlEl = el;
   }

   public override bool TrySetMember(SetMemberBinder binder, object value) {
      return false;
   }

   public override bool TryGetMember(GetMemberBinder binder, out object result) {
      XmlElement el = (XmlElement)_xmlEl.SelectSingleNode(binder.Name);
      if (el != null) {
         // wrap the element we found in a new DynamicXmlElement object
         result = new DynamicXmlElement(el);
         return true;
      }
      else if (binder.Name == "root") {
         // special case for handling references to "root"
         result = new DynamicXmlElement(_xmlEl.OwnerDocument.DocumentElement);
         return true;
      }
      else {
         // feel free to change this to prevent having accidental null reference issues
         // by just setting the result to a DynamicXmlElement with a null element and 
         // handling _xmlEl == null at the start of this method
         result = null;
         return false;
      }
   }

   public override string ToString() {
      return _xmlEl.InnerText;
   }
}
下面是如何调用代码。请注意,此代码仅在C#4.0中编译

namespace ConsoleApplication4 {
   class Program {
      static void Main(string[] args) {
         var xmlstr = "<r><subnode><subsubnode>ABCs of dynamic classes</subsubnode></subnode></r>";
         dynamic xml = new DynamicXmlElement(xmlstr);
         Console.WriteLine(xml.subnode.root.subnode.subsubnode); // take the long way around...
         Console.ReadKey(true);
      }
   }
}
命名空间控制台应用程序4{
班级计划{
静态void Main(字符串[]参数){
var xmlstr=“动态类的ABC”;
动态xml=新的DynamicXmlElement(xmlstr);
Console.WriteLine(xml.subnode.root.subnode.subsubsubnode);//走远一点。。。
Console.ReadKey(true);
}
}
}
我不能完全相信这一点。对于Boo,早在2003年,C#就已经慢慢地获得了Boo在.NET中多年来所拥有的功能……首先是类型推断,现在是IQuackFu风格的
DynamicObject
。一旦他们实现了语言宏以便您可以制作DSL,我想他们就会迎头赶上了


我将把编写这段代码的新样式XElement版本留给读者。

如果任何类型发生更改,它将是XDocument,而不是XmlDocument。另外,这个问题的答案是针对C#的吗?好吧,
动态
是C#的一个特性,所以是的,是针对C#的。我个人认为,它是“静态的”。这就是XPath的用途……至于PowerShell,它使用大量的反射魔法使[大多数]一切都是“动态的”。您如何引用名称中包含破折号(例如
)或点(例如
)的元素这样呢?还有,如果子属性
x
和子元素
x
同时存在,你会如何区分它们?如果一个类支持一个新的接口,而这个接口在编写代码时并不存在,它会如何破坏现有的代码?有趣的答案,但我的问题是,为什么没有任何类型可以在C#?中处理
xmlDoc.root.subnode.subsubsubnode
语法(如果我理解正确,可能通过实现
IDynamicMetaObjectProvider
)但是你可以在C#4中做到这一点,你可以自己管理成员查找,例如,请参见。是的,对象可以是真正动态的。请参见MSDN上的
DynamicObject
expandooObject
类,以及它们实现的接口。因此,答案实际上是不正确的,例如
XmlDocument
很可能添加abi在将来的版本中,可以作为
((动态)root).foo.bar.baz
访问。@Pavel:当然,我读过关于DynamicObject和ExpandoObject的内容。但是,要通过运行时动态“expando”使XmlDocument真正可导航要困难得多属性,而不是简单地将IDynamicMetaObjectProvider添加到XmlDocument。您需要为树中的每个xml对象添加“动态”功能,