更新时间: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小提琴.