扩展System.Xml.Linq.XElement -内部CloneNode

本文关键字:内部 CloneNode XElement Linq System Xml 扩展 | 更新日期: 2023-09-27 18:08:43

我有类Foo扩展System.Xml.Linq.XElement,但当我调用

Foo parent = ..; Foo child = ..; parent.Add(child);

添加的子节点不是Foo类型,而是XElement类型。

这是因为internal abstract XNode CloneNode()Add方法中被调用。

我不能重写这个,因为内部。在这种情况下我有什么选择?我不想重写每个调用CloneNode()的函数。

扩展System.Xml.Linq.XElement -内部CloneNode

现在我有一个丑陋的解决方案,更像是临时hack而不是解决方案,一般不工作,只是修补当前的代码。我不确定有什么好的解决方案,除了重写代码而不扩展XElement,所以我将发布这篇文章。

CloneNode仅在父字段不为空时在Add中调用,但父属性只有get,并且父字段是内部的。解决这个问题最简单的方法就是在XElementExtended:

中隐藏XElement Add
static FieldInfo parentProperty = typeof(XElementExtended).GetField("parent",
            BindingFlags.NonPublic | BindingFlags.Instance);
public void Add(XElementExtended element)
{
    var el = new XElementExtended(element);
    parentProperty.SetValue(el, null);
    base.Add(el);
}

XElement作为实体是XML模型本身的一部分。如果要向XML添加一些功能(如新类型的Node),则需要扩展它。即使这样,XNode实现仍然是正确的,因为它对您的新XML一无所知。据我所知,XML本身是不可扩展的,例如,你不能添加一种新的节点。

如果您试图类型化您的XML数据,那么正确的方法将是单独构建您的数据模型,并在根实体上实现读/写方法。

如果你想标记你的元素,那么你必须要么直接从XDocument构建一个围绕整个模型的包装器,要么用Dictionary<XElement, something>索引旁边的信息。