代码之家  ›  专栏  ›  技术社区  ›  Wes P

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

  •  122
  • Wes P  · 技术社区  · 16 年前

    我有没有办法在中序列化对象。NET中没有XML命名空间也会自动序列化吗?似乎是默认的。NET认为应该包含XSI和XSD名称空间,但我不希望它们出现在那里。

    6 回复  |  直到 16 年前
        1
  •  126
  •   Cheeso    16 年前

    啊。…没关系。总是在问题提出后进行搜索才能得到答案。正在序列化的对象是 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);
    
        2
  •  19
  •   datguy mmoon    7 年前

    如果你想摆脱多余的 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/");   
    
        3
  •  7
  •   michal.jakubeczy    7 年前

    如果你想删除命名空间,你可能还想删除版本,为了节省你的搜索时间,我添加了这个功能,所以下面的代码可以同时完成这两项工作。

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

    我建议使用这个辅助类:

    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
  •   vinjenzo    11 年前

    如果在从生成的类序列化为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 /> ...