首页 文章

如何在不获取xmlns =“...”的情况下将对象序列化为XML?

提问于
浏览
94

有没有办法让我在.NET中序列化一个对象,而XML Namespaces也不会自动序列化?似乎默认情况下.NET认为应该包含XSI和XSD名称空间,但我不希望它们存在 .

5 回答

  • 7

    啊......没关系 . 在提出问题后,始终是搜索产生答案 . 我被序列化的对象是 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);
    
  • 122

    如果你想摆脱额外的 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/");
    
  • 4

    如果你想删除命名空间,你可能还想删除版本,为了节省你的搜索我添加了这个功能,所以下面的代码将同时执行这两个 .

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

    我建议这个助手类:

    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
    }
    

    :)

  • 18

    如果你无法为每个元素删除额外的xmlns属性,那么当从生成的类序列化为xml时(例如:当使用 xsd.exe 时),所以你有类似的东西:

    <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 /> ...
    

相关问题