如何序列化一个对象到XML而不会得到xmlns =“…”?
有没有办法让我序列化.NET中的对象没有XML命名空间自动序列化呢? 看来,默认情况下,.NET认为应该包含XSI和XSD命名空间,但我不希望它们在那里。
啊…没关系。 在提出问题之后总是寻找答案。 我正在序列化的对象是obj
,并已被定义。 用一个空的命名空间添加一个XMLSerializerNamespace到这个集合就可以做到这一点。
在VB中是这样的:
Dim xs As New XmlSerializer(GetType(cEmploymentDetail)) Dim ns As New XmlSerializerNamespaces() ns.Add("", "") Dim settings As New XmlWriterSettings() settings.OmitXmlDeclaration = True Using ms As New MemoryStream(), _ sw As XmlWriter = XmlWriter.Create(ms, settings), _ sr As New StreamReader(ms) xs.Serialize(sw, obj, ns) ms.Position = 0 Console.WriteLine(sr.ReadToEnd()) End Using
在C#中是这样的:
//Create our own namespaces for the output XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); //Add an empty namespace and empty value ns.Add("", ""); //Create the serializer XmlSerializer slz = new XmlSerializer(someType); //Serialize the object with our own namespaces (notice the overload) slz.Serialize(myXmlTextWriter, someObject, ns);
如果你想摆脱额外的xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
和xmlns:xsd="http://www.w3.org/2001/XMLSchema"
,但仍然保留自己的命名空间xmlns="http://schemas.YourCompany.com/YourSchema/"
,除了这个简单的更改之外,您使用与上面相同的代码:
// Add lib namespace with empty prefix ns.Add("", "http://schemas.YourCompany.com/YourSchema/");
你可以在这里find更多的Xml序列化技巧和技巧。
如果你想删除命名空间,你也可以删除版本,为了保存你的search我已经添加了这个function,所以下面的代码将做到这一点。
我也用一个通用的方法包装它,因为我正在创build非常大的xml文件,这些文件太大而无法在内存中序列化,所以我打断了我的输出文件,并以较小的“块”序列化它:
public static string XmlSerialize<T>(T entity) where T : class { // removes version XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlSerializer xsSubmit = new XmlSerializer(typeof(T)); StringWriter sw = new StringWriter(); using (XmlWriter writer = XmlWriter.Create(sw, settings)) { // removes namespace var xmlns = new XmlSerializerNamespaces(); xmlns.Add(string.Empty, string.Empty); xsSubmit.Serialize(writer, entity, xmlns); return sw.ToString(); // Your XML } }
我build议这个帮手类:
public static class Xml { #region Fields private static readonly XmlWriterSettings WriterSettings = new XmlWriterSettings {OmitXmlDeclaration = true, Indent = true}; private static readonly XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces(new[] {new XmlQualifiedName("", "")}); #endregion #region Methods public static string Serialize(object obj) { if (obj == null) { return null; } return DoSerialize(obj); } private static string DoSerialize(object obj) { using (var ms = new MemoryStream()) using (var writer = XmlWriter.Create(ms, WriterSettings)) { var serializer = new XmlSerializer(obj.GetType()); serializer.Serialize(writer, obj, Namespaces); return Encoding.UTF8.GetString(ms.ToArray()); } } public static T Deserialize<T>(string data) where T : class { if (string.IsNullOrEmpty(data)) { return null; } return DoDeserialize<T>(data); } private static T DoDeserialize<T>(string data) where T : class { using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(data))) { var serializer = new XmlSerializer(typeof (T)); return (T) serializer.Deserialize(ms); } } #endregion }
🙂
如果你无法为每个元素去除额外的xmlns属性,当从生成的类序列化到xml(例如:当使用xsd.exe时),所以你有这样的东西:
<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />
那么我会和你分享什么对我有用(以前的答案和我在这里find的)
显式设置所有不同的xmlns,如下所示:
Dim xmlns = New XmlSerializerNamespaces() xmlns.Add("one", "urn:names:specification:schema:xsd:one") xmlns.Add("two", "urn:names:specification:schema:xsd:two") xmlns.Add("three", "urn:names:specification:schema:xsd:three")
然后将其传递给序列化
serializer.Serialize(writer, object, xmlns);
您将在根元素中声明三个名称空间,并且不需要在其他元素中生成相应的前缀
<root xmlns:one="urn:names:specification:schema:xsd:one" ... /> <one:Element /> <two:ElementFromAnotherNameSpace /> ...