序列化没有xmlns

Caf*_*eek 16 c# namespaces xml-serialization

我有几个扩展方法来处理我的类的序列化,因为它可能是一个耗时的过程,它们每个类创建一次,并由此方法分发.

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];
}
Run Code Online (Sandbox Code Playgroud)

这是通过扩展方法调用的.Serialize()

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,在序列化自动生成的类时,它们会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>
Run Code Online (Sandbox Code Playgroud)

而不是相同,减去xmlns="http://tempuri.org/"属性.

请帮忙,谢谢,这让我抓狂!

编辑:

我知道问题,而不是如何解决它.

我的班级,不仅仅是简单的类型.

它包含具有其他类的类型的属性.这也是使用XmlTypeAttribute(Namespace = "http://tempuri.org/")属性自动生成的.所以正在发生的事情是,当序列化发生时,它序列化我的类的属性,它们不会通过我的自定义序列化,因此,应用了属性而不是覆盖.

现在我只需要弄清楚如何跳过那个篮圈.有什么想法?

编辑2:

以下工作序列化WITHOUT xmlns ...但我在反序列化结束时遇到问题,只是还不确定它是否相关

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];
}
Run Code Online (Sandbox Code Playgroud)

EDIT3:使用如何使用C#从XML中删除所有名称空间的解决方案结束了

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)));
}
Run Code Online (Sandbox Code Playgroud)

Vah*_*idN 53

一个工作的解决方案,记录!

var ns = new XmlSerializerNamespaces();
ns.Add("", ""); 
var serializer = new XmlSerializer(yourType); 
serializer.Serialize(xmlTextWriter, someObject, ns);
Run Code Online (Sandbox Code Playgroud)

  • 为了记录,这将删除`xsi`和`xsd`,但是它将添加一个新的`xmlns:prefix = <namespace>`并且如果你有`XmlTypeAttribute`s指定的命名空间,则为你的所有标记添加前缀.你的课程. (10认同)
  • 不得不说,不。我在每个元素上都得到 `xmlns=""` 。 (2认同)

mar*_*c_s 5

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

XmlSerializer newSerializer = 
   new XmlSerializer(typeOfT, "");
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果您确实需要定义XmlAttributeOverrides和默认命名空间,则没有简单的构造函数重载- 因此您可以跳过XmlAttributeOverrides并使用我提到的构造函数,或者您需要使用定义所有可能参数的构造函数(包括 XmlAttributeOverrides 和默认 XML命名空间 - 以及更多)。

  • 没有工作。其实不是答案。VihidN 的回答对我有用! (5认同)