How to serialize an object to XML without getting xmlns="..."?

有没有一种方法可以在。NET 而没有自动序列化的 XML 名称空间也?似乎默认情况下。NET 认为应该包括 XSI 和 XSD 名称空间,但我不希望它们出现在那里。

118129 次浏览

Ahh... nevermind. It's always the search after the question is posed that yields the answer. My object that is being serialized is obj and has already been defined. Adding an XMLSerializerNamespace with a single empty namespace to the collection does the trick.

在 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

像这样:

//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/");

If you are unable to get rid of extra xmlns attributes for each element, when serializing to xml from generated classes (e.g.: when xsd.exe was used), so you have something like:

<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />

然后我会与你分享什么为我工作(以前的答案和什么我发现 here的组合)

将所有不同的 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 /> ...

我建议这个助手类:

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
}

:)

如果你想删除命名空间,你可能也想删除版本,为了节省你搜索,我已经添加了这个功能,所以下面的代码将做两者。

I've also wrapped it in a generic method as I'm creating very large xml files which are too large to serialize in memory so I've broken my output file down and serialize it in smaller "chunks":

    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));
using (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
}
}
        XmlWriterSettings settings = new XmlWriterSettings
{
OmitXmlDeclaration = true
};


XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");


StringBuilder sb = new StringBuilder();


XmlSerializer xs = new XmlSerializer(typeof(BankingDetails));


using (XmlWriter xw = XmlWriter.Create(sb, settings))
{
xs.Serialize(xw, model, ns);
xw.Flush();
return sb.ToString();
}