代码之家  ›  专栏  ›  技术社区  ›  CaffGeek

不使用xmlns序列化

  •  14
  • CaffGeek  · 技术社区  · 14 年前

    我有两个扩展方法来处理我的类的序列化,因为这可能是一个耗时的过程,所以每个类创建一个扩展方法,并由这个方法分发。

    public static XmlSerializer GetSerializerFor(Type typeOfT)
    {
        if (!serializers.ContainsKey(typeOfT))
        {
            var xmlAttributes = new XmlAttributes();
            var xmlAttributeOverrides = new XmlAttributeOverrides();
    
            System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT));
    
            xmlAttributes.Xmlns = false;
            xmlAttributeOverrides.Add(typeOfT, xmlAttributes);
    
            var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides);
            serializers.Add(typeOfT, newSerializer);
        }
    
        return serializers[typeOfT];
    }
    

    public static XElement Serialize(this object source)
    {
        try
        {
            var serializer = XmlSerializerFactory.GetSerializerFor(source.GetType());
            var xdoc = new XDocument();
            using (var writer = xdoc.CreateWriter())
            {
                serializer.Serialize(writer, source, new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") }));
            }
    
            return (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing");
        }
        catch (Exception x)
        {
            return new XElement("Error", x.ToString());
        }
    }
    

    XmlTypeAttribute(Namespace="http://tempuri.org/")

    这会导致非自动生成的对应项的反序列化失败。

    我需要序列化程序完全忽略并且不应用名称空间,但是我在第一个代码块中编写的代码似乎并没有删除它,我仍然会以这样的xml结束

    <Note>
      <ID xmlns="http://tempuri.org/">12</ID>
      <Author xmlns="http://tempuri.org/">
        <ID>1234</ID>
        <Type>Associate</Type>
        <IsAvailable>false</IsAvailable>
      </Author>
      <Created xmlns="http://tempuri.org/">2010-06-22T09:38:01.5024351-05:00</Created>
      <Text xmlns="http://tempuri.org/">This is an update</Text>
    </Note>
    

    xmlns="http://tempuri.org/" 属性。

    请帮帮我,谢谢,这快把我逼疯了!

    我知道问题所在,只是不知道如何解决。

    我的课,不仅仅是简单的类型。

    它包含具有其他类类型的属性。也可以通过 XmlTypeAttribute(Namespace = "http://tempuri.org/")

    编辑2:

    public static XmlSerializer GetSerializerFor(Type typeOfT)
    {
        if (!serializers.ContainsKey(typeOfT))
        {
            var xmlAttributes = new XmlAttributes();
            var xmlAttributeOverrides = new XmlAttributeOverrides();
    
            System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT));
    
            xmlAttributes.XmlType = new XmlTypeAttribute
            {
                Namespace = ""
            };
    
            xmlAttributes.Xmlns = false;
    
            var types = new List<Type> {typeOfT, typeOfT.BaseType};
    
            foreach (var property in typeOfT.GetProperties())
            {
                types.Add(property.PropertyType);
            }
    
            types.RemoveAll(t => t.ToString().StartsWith("System."));
    
            foreach (var type in types)
            {
                xmlAttributeOverrides.Add(type, xmlAttributes);
            }
    
            var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides);
            //var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides, extraTypes.ToArray(), new XmlRootAttribute(), string.Empty);
            //var newSerializer = new XmlSerializer(typeOfT, string.Empty);
    
            serializers.Add(typeOfT, newSerializer);
        }
    
        return serializers[typeOfT];
    }
    

    编辑3: How to remove all namespaces from XML with C#?

    public static XElement RemoveAllNamespaces(this XElement source)
    {
        return !source.HasElements
                   ? new XElement(source.Name.LocalName)
                         {
                             Value = source.Value
                         }
                   : new XElement(source.Name.LocalName, source.Elements().Select(el => RemoveAllNamespaces(el)));
    }
    
    3 回复  |  直到 7 年前
        1
  •  5
  •   marc_s HarisH Sharma    14 年前

    没问题-只需将空字符串作为默认命名空间传递给XML序列化程序:

    XmlSerializer newSerializer = 
       new XmlSerializer(typeOfT, "");
    

    不幸的是,如果您真的需要定义 XmlAttributeOverrides 以及默认名称空间-因此您可以跳过 XmlAttributeOverrides属性 然后使用我提到的构造函数,或者您需要使用定义所有可能参数的构造函数(包括XmlAttributeOverrides和默认XML名称空间,以及其他一些)。

        2
  •  57
  •   VahidN    13 年前

    一个有效的解决方案, 记录在案!

    var ns = new XmlSerializerNamespaces();
    ns.Add("", ""); 
    var serializer = new XmlSerializer(yourType); 
    serializer.Serialize(xmlTextWriter, someObject, ns);
    
        3
  •  1
  •   user3444796    10 年前
     public static byte[] SerializeByteByType(object objectToSerialize, Type type)
        {
            XmlWriterSettings xmlSetting = new XmlWriterSettings()
            {
                NewLineOnAttributes = false,
                OmitXmlDeclaration = true,
                Indent = false,
                NewLineHandling = NewLineHandling.None,
                Encoding = Encoding.UTF8,
                NamespaceHandling = NamespaceHandling.OmitDuplicates
            };
    
            using (MemoryStream stm = new MemoryStream())
            {
                using (XmlWriter writer = XmlWriter.Create(stm, xmlSetting))
                {
                    var xmlAttributes = new XmlAttributes();
                    var xmlAttributeOverrides = new XmlAttributeOverrides();
    
                    xmlAttributes.Xmlns = false;
                    xmlAttributes.XmlType = new XmlTypeAttribute() { Namespace = "" };
                    xmlAttributeOverrides.Add(type, xmlAttributes);
    
                    XmlSerializer serializer = new XmlSerializer(type, xmlAttributeOverrides);
                    //Use the following to serialize without namespaces
                    XmlSerializerNamespaces xmlSrzNamespace = new XmlSerializerNamespaces();
                    xmlSrzNamespace.Add("", "");
    
                    serializer.Serialize(writer, objectToSerialize, xmlSrzNamespace);
                    stm.Flush();
                    stm.Position = 0;
                }
    
                return stm.ToArray();
            }
        }         
    
        4
  •  0
  •   Nikhil Bandivan    5 年前
        public static string SerializeToXml(object obj)
        {
            UTF8Encoding encoding = new UTF8Encoding(false);
    
            var xmlAttributes = new XmlAttributes();
            xmlAttributes.Xmlns = false;
            xmlAttributes.XmlType = new XmlTypeAttribute() { Namespace = "" };
    
            var xmlAttributeOverrides = new XmlAttributeOverrides();
    
            var types = obj.GetType().Assembly.GetTypes().Where(t => string.Equals(t.Namespace, obj.GetType().Namespace, StringComparison.Ordinal));
            foreach (var t in types) xmlAttributeOverrides.Add(t, xmlAttributes);
    
            XmlSerializer sr = new XmlSerializer(obj.GetType(), xmlAttributeOverrides);
    
            MemoryStream memoryStream = new MemoryStream();
            StreamWriter writer = new StreamWriter(memoryStream, encoding);
    
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add(string.Empty, string.Empty);
    
            // get the stream from the writer
            memoryStream = writer.BaseStream as MemoryStream;
    
            sr.Serialize(writer, obj, namespaces);
    
            // apply encoding to the stream 
            return (encoding.GetString(memoryStream.ToArray()).Trim());
        }
    

    它甚至适用于包含嵌套对象的复杂对象 用户3444796和导师的学分