如何将对象序列化为XML而不获取xmlns= "…" ?

时间:2023-02-09 15:24:32

Is there a way for me to serialize an object in .NET without the XML Namespaces automatically serializing also? It seems that by default .NET believes the XSI and XSD namespaces should be included, but I don't want them there.

是否有一种方法可以让我在.NET中序列化一个对象,而不使用XML名称空间自动序列化?似乎默认情况下。net认为应该包含XSI和XSD名称空间,但我不希望它们出现在那里。

5 个解决方案

#1


117  

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.

啊…别介意。问题提出后的搜寻才能得到答案。正在被序列化的对象是obj,并且已经被定义。向集合添加具有单个空名称空间的XMLSerializerNamespace可以实现这一点。

In VB like this:

在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

in C# like this:

在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);

#2


17  

If you want to get rid of the extra xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" and xmlns:xsd="http://www.w3.org/2001/XMLSchema", but still keep your own namespace xmlns="http://schemas.YourCompany.com/YourSchema/", you use the same code as above except for this simple change:

如果您想摆脱额外的xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"和xmlns:xsd="http://www.w3.org/2001/XMLSchema",但仍然保留自己的名称空间xmlns=" http://schemas.yourcompany.com/schema/ "

//  Add lib namespace with empty prefix  
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");   

#3


7  

If you want to remove the namespace you may also want to remove the version, to save you searching I've added that functionality so the below code will do both.

如果您想删除名称空间,您可能还想删除版本,为了保存搜索,我添加了该功能,因此下面的代码将同时执行这两个功能。

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":

我还将它封装在一个通用的方法中,因为我正在创建非常大的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));
        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
        }
    }

#4


5  

I Suggest this helper class:

我建议这个助手类:

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
}

:)

:)

#5


4  

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:

如果您无法摆脱每个元素的额外xmlns属性,那么在从生成的类序列化xml时(例如:when xsd)。使用了exe),因此您有如下内容:

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

then i would share with you what worked for me (a mix of previous answers and what i found here)

然后我会和你们分享对我有用的东西(混合了之前的答案和我在这里发现的)

explicitly set all your different xmlns as follows:

显式设置所有不同的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")

then pass it to the serialize

然后将其传递给序列化。

serializer.Serialize(writer, object, xmlns);

you will have the three namespaces declared in the root element and no more needed to be generated in the other elements which will be prefixed accordingly

您将在根元素中声明三个名称空间,并且不需要在其他元素中生成相应的前缀。

<root xmlns:one="urn:names:specification:schema:xsd:one" ... />
   <one:Element />
   <two:ElementFromAnotherNameSpace /> ...

#1


117  

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.

啊…别介意。问题提出后的搜寻才能得到答案。正在被序列化的对象是obj,并且已经被定义。向集合添加具有单个空名称空间的XMLSerializerNamespace可以实现这一点。

In VB like this:

在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

in C# like this:

在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);

#2


17  

If you want to get rid of the extra xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" and xmlns:xsd="http://www.w3.org/2001/XMLSchema", but still keep your own namespace xmlns="http://schemas.YourCompany.com/YourSchema/", you use the same code as above except for this simple change:

如果您想摆脱额外的xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"和xmlns:xsd="http://www.w3.org/2001/XMLSchema",但仍然保留自己的名称空间xmlns=" http://schemas.yourcompany.com/schema/ "

//  Add lib namespace with empty prefix  
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");   

#3


7  

If you want to remove the namespace you may also want to remove the version, to save you searching I've added that functionality so the below code will do both.

如果您想删除名称空间,您可能还想删除版本,为了保存搜索,我添加了该功能,因此下面的代码将同时执行这两个功能。

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":

我还将它封装在一个通用的方法中,因为我正在创建非常大的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));
        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
        }
    }

#4


5  

I Suggest this helper class:

我建议这个助手类:

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
}

:)

:)

#5


4  

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:

如果您无法摆脱每个元素的额外xmlns属性,那么在从生成的类序列化xml时(例如:when xsd)。使用了exe),因此您有如下内容:

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

then i would share with you what worked for me (a mix of previous answers and what i found here)

然后我会和你们分享对我有用的东西(混合了之前的答案和我在这里发现的)

explicitly set all your different xmlns as follows:

显式设置所有不同的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")

then pass it to the serialize

然后将其传递给序列化。

serializer.Serialize(writer, object, xmlns);

you will have the three namespaces declared in the root element and no more needed to be generated in the other elements which will be prefixed accordingly

您将在根元素中声明三个名称空间,并且不需要在其他元素中生成相应的前缀。

<root xmlns:one="urn:names:specification:schema:xsd:one" ... />
   <one:Element />
   <two:ElementFromAnotherNameSpace /> ...