且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用XmlSerializer在大型文档中插入节点

更新时间:2023-11-07 12:16:58

中所述,在在.NET中序列化一个对象? XmlSerializer 在序列化时总是会有益地添加 xsi xsd 命名空间.如果您不希望这样做,则需要调用 Serialize 的重载,在其中可以指定所需的初始名称空间,例如 XmlSerializer.Serialize(XmlWriter,Object,XmlSerializerNamespaces) .以下扩展方法可以解决问题:

As explained in Omitting all xsi and xsd namespaces when serializing an object in .NET?, XmlSerializer will always helpfully add the xsi and xsd namespaces when serializing. If you don't want that, you need to call an overload of Serialize where the required initial namespaces can be specified, e.g. XmlSerializer.Serialize(XmlWriter, Object, XmlSerializerNamespaces). The following extension method does the trick:

public static class XmlNodeExtensions
{
    public static XmlNode ReplaceWithSerializationOf<T>(this XmlNode node, T replacement)
    {
        if (node == null)
            throw new ArgumentNullException();
        var parent = node.ParentNode;
        var serializer = new XmlSerializer(replacement == null ? typeof(T) : replacement.GetType());

        using (var writer = node.CreateNavigator().InsertAfter())
        {
            // WriteWhitespace needed to avoid error "WriteStartDocument cannot
            // be called on writers created with ConformanceLevel.Fragment."
            writer.WriteWhitespace("");

            // Set up an appropriate initial namespace.
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add(node.GetNamespaceOfPrefix(node.NamespaceURI), node.NamespaceURI);

            // Serialize
            serializer.Serialize(writer, replacement, ns);
        }

        var nextNode = node.NextSibling;
        parent.RemoveChild(node);
        return nextNode;
    }
}

然后按如下所示使用它:

Then use it as follows:

var newCar = new Car { make = "BMW" };
var node = doc.DocumentElement.SelectSingleNode("myns:Cars/myns:Car[@make='Ford']", nsMgr);
node = node.ReplaceWithSerializationOf(newCar);
var parent = node.ParentNode;

然后,为 doc 生成的XML将是:

Afterwards, the XML generated for doc will be:

<RootNode xmlns="http://MyNamespace">
  <Cars>
    <Car make="Volkswagen" />
    <Car make="BMW" />
    <Car make="Opel" />
  </Cars>
</RootNode>

示例工作 .Net小提琴.