在将XML值反序列化为枚举时处理额外的空格

时间:2015-07-06 17:57:50

标签: c# xml serialization enums

我一直想知道是否可以这样做。

如果XML响应的值不正确,需要映射到枚举,这将是一个很好的帮助。

我特别处理的情况是,当预期值有一个尾随空格且枚举期望它没有时。

XML:

<Foo>
    <Bar>EnumValue </Bar>
</Foo>

枚举:

public enum MyEnum
{
    [XmlEnum("EnumValue")]
    EnumValue
}

类:

public class Foo
{
    [XmlElement("Bar")]
    public MyEnum myEnum { get; set; }
}

我使用自定义属性(而不是&#34; XmlEnum&#34;)进行调查以修剪值,但在反序列化过程中似乎没有达到它。

有没有办法在反序列化之前/期间修剪XML值(需要时),以便可以正确地将值映射到枚举?

-

我应该补充一点,我不能对XML的发送方式进行任何更改,我只能处理响应。

此外,只需将属性参数更改为[XmlEnum(&#34; EnumValue&#34;)]即可解决问题,但这并不令人满意,因为XML值可能会在以后更改。

3 个答案:

答案 0 :(得分:0)

如果XML不是很大并且/或者性能不太可能成为问题,那么您可以使用LINQ to XML解析它,并在使用{{1}进行反序列化之前修复任何不正确的值。 }}:

XmlSerializer

答案 1 :(得分:0)

请试试这个:

public class Foo
{
    [XmlIgnore]
    public MyEnum myEnum { get; set; }

    [XmlElement("Bar")]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public string _myEnum
    {
        get { return myEnum.ToString(); }
        set { myEnum = (MyEnum)Enum.Parse(typeof(MyEnum), value.Trim()); }
    }
}

答案 2 :(得分:0)

不幸的是,没有任何事件在未知的枚举值上触发,它允许您替换自己的解析算法。此外,XmlEnumAttribute未设置AttributeUsage.AllowMultiple = true,因此您无法使用前导和尾随空格的各种组合添加多个枚举别名。

一种可能的解决方法是add a string-valued property to your class并手动进行解析。另一种方法是添加一个封装结构,封装enum来处理解析:

public class Foo
{
    [XmlIgnore]
    public MyEnum myEnum { get; set; }

    [XmlElement("Bar")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public XmlEnumWrapper<MyEnum> myEnumXml { get { return myEnum; } set { myEnum = value; } }
}

public struct XmlEnumWrapper<TEnum> : IEquatable<XmlEnumWrapper<TEnum>> where TEnum : struct, IConvertible, IComparable, IFormattable
{
    TEnum value;

    public XmlEnumWrapper(TEnum value)
    {
        this.value = value;
    }

    public static implicit operator TEnum(XmlEnumWrapper<TEnum> wrapper)
    {
        return wrapper.Value;
    }

    public static implicit operator XmlEnumWrapper<TEnum>(TEnum anEnum)
    {
        return new XmlEnumWrapper<TEnum>(anEnum);
    }

    public static bool operator ==(XmlEnumWrapper<TEnum> first, XmlEnumWrapper<TEnum> second)
    {
        return first.Equals(second);
    }

    public static bool operator !=(XmlEnumWrapper<TEnum> first, XmlEnumWrapper<TEnum> second)
    {
        return !first.Equals(second);
    }

    [XmlIgnore]
    public TEnum Value { get { return value; } private set { this.value = value; } }

    [XmlText]
    public string ValueString
    {
        get
        {
            return Value.ToString();
        }
        set
        {
            // See here if one needs to parse XmlEnumAttribute attributes
            // http://stackoverflow.com/questions/3047125/retrieve-enum-value-based-on-xmlenumattribute-name-value
            value = value.Trim();
            Value = (TEnum)Enum.Parse(typeof(TEnum), value, false);
        }
    }

    #region IEquatable<XmlEnumWrapper<TEnum>> Members

    public bool Equals(XmlEnumWrapper<TEnum> other)
    {
        return EqualityComparer<TEnum>.Default.Equals(Value, other.Value);
    }

    #endregion

    public override bool Equals(object obj)
    {
        if (obj is XmlEnumWrapper<TEnum>)
            return Equals((XmlEnumWrapper<TEnum>)obj);
        return Value.Equals(obj);
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }

    public override string ToString()
    {
        return Value.ToString();
    }
}

这也允许您添加同义词处理或处理未知值,而不必在必要时抛出异常。