不使用xmlns进行序列化 [英] Serializing WITHOUT xmlns

查看:85
本文介绍了不使用xmlns进行序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a couple extension methods that handle serialization of my classes, and since it can be a time consuming process, they are created once per class, and handed out by this method.

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];
}

这由扩展方法.Serialize()调用

This is called by the extension method .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());
    }
}

不幸的是,当序列化自动生成的类时,它们具有属性XmlTypeAttribute(Namespace="http://tempuri.org/")应用于它们.

Unfortunately, when Serializing classes that are auto-generated, they have the attribute XmlTypeAttribute(Namespace="http://tempuri.org/") applied to them.

这会导致非自动生成的对等对象的反序列化失败.

This causes the deserialization by the the non-auto-generated counterparts to fail.

我需要序列化程序完全忽略并且不应用命名空间,但是我在第一段代码中写的似乎并没有将其删除,我仍然会得到这样的xml

I need the serializer to completely ignore and not apply the namespace, but what I have written in the first block of code doesn't seem to remove it, I still end up with xml like this

<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/"属性代替原来的

请帮助,谢谢,这让我发疯了!

Please help, thanks, this is driving me crazy!

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

I know the problem, just not how to fix it.

我的课不仅仅是简单的类型.

My class, isn't just full of simple types.

它包含具有其他类类型的属性.也可以使用XmlTypeAttribute(Namespace = "http://tempuri.org/")属性自动生成.因此,发生的事情是,当发生序列化时,它对我的​​类的属性进行了序列化,它们没有经过我的自定义序列化,因此,该属性已被应用且未被覆盖.

It contains properties with types of other classes. Which are also auto-generated with the XmlTypeAttribute(Namespace = "http://tempuri.org/") attribute. So what is happening, is that when serialization occurs, and it serializes the properties of my class, they aren't going through my custom serialization, and thus, are having the attribute applied and not overridden.

现在,我只需要弄清楚如何跳那个箍.有什么想法吗?

Now I just need to figure out how to jump that hoop. Any thoughts as to how?

下面的方法可以在不使用xmlns的情况下进行序列化...但是我在反序列化方面遇到了问题,只是不确定是否与之相关

The following works to serialize WITHOUT xmlns... but I'm having a problem on the deserialization end, just not yet sure if it's related or not

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];
}

最终使用来自的解决方案 如何使用C#从XML中删除所有命名空间?

Ended up using solution from 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)));
}

推荐答案

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

No problem - just pass an empty string as the default namespace to the XML serializer:

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

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

Unfortunately, there's no easy constructor overload if you really need to define the XmlAttributeOverrides and the default namespace - so either you can skip the XmlAttributeOverrides and use that constructor I mentioned, or you need to use the one that defines all possible parameters (including XmlAttributeOverrides and default XML namespaces - and a few more).

这篇关于不使用xmlns进行序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆