无法以所需方式将 XML 属性值解析为 C# 枚举

Unable to parse XML attribute value into C# Enum in a desired way

我在 C#

中有以下 class

public class DynamicFieldParameter
{
        [XmlAttribute]
        public string ParentName { get; set; }

        [XmlAttribute]
        public string Label { get; set; }

        [XmlAttribute]
        public string ParameterName { get; set; }

        [XmlAttribute]
        public string Value { get; set; }

        [XmlAttribute("ParameterValueType")]
        public ParameterValueType ValueTypeID { get; set; }
}

然后我有以下枚举,


    [Serializable]
    public enum ParameterValueType
    {
        [XmlEnum(Name = "0")]
        Conditional,
        [XmlEnum(Name = "1")]
        Static
    }

我正在尝试解析以下 XML、

<?xml version="1.0" encoding="UTF-8"?>
<DynamicFormExport Version="2">
  <DynamicForm>
    <DynamicField>
      <ListParameters>
        <Parameter ParentName="spGetPickListItems" ParameterName="DisplayCode" 
             Label="Display Code" Value="3" ValueTypeID="1" />
      </ListParameters>
    </DynamicField>
  </DynamicForm>
</DynamicFormExport>

我正在使用下面的代码来解析 XML,


        /// <summary>
        /// Iterates through a xml reader and loads a parameter set
        /// </summary>
        /// <param name="reader">Xml reader. Position is expected to be at the parent node of a parameter collection (e.g. ListParameters)</param>
        /// <returns></returns>
        private List<DynamicFieldParameter> LoadParametersFromXmlReader(XmlReader reader)
        {
            List<DynamicFieldParameter> parameters = new List<DynamicFieldParameter>();
            if (reader == null)
                return parameters;

            XmlReader paramReader = reader.ReadSubtree();
            paramReader.MoveToContent();
            paramReader.Read();

            string paramXml = paramReader.ReadOuterXml();
            while (!string.IsNullOrEmpty(paramXml))
            {
                parameters.Add(DynamicFieldParameter.FromXml(paramXml));
                paramXml = paramReader.ReadOuterXml();
            }

            return parameters;
        }

我在调试器中看到的是,我得到 ValueTypeID = Conditional,即使我正在解析的 XML 有 ValueTypeID = 1,我希望我的 ValueTypeID 是静态的。

我在解析时做错了什么?

下面显示了一种使用 System.Xml.Serialization.

获取所需属性值的方法

为反序列化方法创建一个 class(名称:HelperXml.cs)。

HelperXml.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    public class HelperXml
    {
        public static T DeserializeXMLFileToObject<T>(string xmlFilename)
        {
            //Usage: Class1 myClass1 = DeserializeXMLFileToObject<Class1>(xmlFilename);

            T rObject = default(T);
            if (String.IsNullOrEmpty(xmlFilename)) return default(T);

            using (System.IO.StreamReader sr = new System.IO.StreamReader(xmlFilename))
            {
                System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));

                //get data
                rObject = (T)serializer.Deserialize(sr);
            }

            return rObject;
        }
    }
}

给定以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<DynamicFormExport Version="2">
  <DynamicForm>
    <DynamicField>
      <ListParameters>
        <Parameter ParentName="spGetPickListItems" ParameterName="DisplayCode" 
             Label="Display Code" Value="3" ValueTypeID="1" />
      </ListParameters>
    </DynamicField>
  </DynamicForm>
</DynamicFormExport>

为以下各项创建 classes:

  • DynamicFormExport
  • 动态表单
  • 动态字段
  • 列表参数
  • 参数

就命名策略而言,为了使 classes 在 VS 中保持所需的顺序,执行以下操作可能会有所帮助:

  • DynamicFormExport(名称:XmlDynamicFormExport
  • DynamicForm(名称:XmlDynamicFormExportDynamicForm
  • 动态字段(名称:XmlDynamicFormExportDynamicFormDynamicField
  • ListParameters(名称:XmlDynamicFormExportDynamicFormDynamicFieldListParameters
  • 参数(名称:XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter

注意:我使用的class名字是上面的class名字加上class名字。 (例如:XmlDynamicFormExport + DynamicForm = XmlDynamicFormExportDynamicForm)。虽然,您 XML 中的名称有些长,因此可能需要不同的命名策略。

XmlDynamicFormExport.cs

using System.Xml;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    [XmlRoot(ElementName = "DynamicFormExport", IsNullable = false)]
    public class XmlDynamicFormExport
    {
        [XmlAttribute(AttributeName = "Version")]
        public int Version { get; set; }

        [XmlElement(ElementName = "DynamicForm")]
        public XmlDynamicFormExportDynamicForm DynamicForm = new XmlDynamicFormExportDynamicForm();
    }
}

XmlDynamicFormExportDynamicForm.cs

using System.Xml;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    public class XmlDynamicFormExportDynamicForm
    {
        [XmlElement(ElementName = "DynamicField")]
        public XmlDynamicFormExportDynamicFormDynamicField DynamicField = new XmlDynamicFormExportDynamicFormDynamicField();
    }
}

XmlDynamicFormExportDynamicFormDynamicField.cs

using System.Xml;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    public class XmlDynamicFormExportDynamicFormDynamicField
    {
        [XmlElement(ElementName = "ListParameters")]
        public XmlDynamicFormExportDynamicFormDynamicFieldListParameters ListParameters = new XmlDynamicFormExportDynamicFormDynamicFieldListParameters();
    }
}

XmlDynamicFormExportDynamicFormDynamicFieldListParameters.cs

注意:虽然在OP的XML中没有显示,但似乎存在不止1个参数,所以我在下面的代码。

using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    public class XmlDynamicFormExportDynamicFormDynamicFieldListParameters
    {
        [XmlElement(ElementName = "Parameter")]
        public List<XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter> Parameter = new List<XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter>();
    }
}

选项 1:

XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter.cs

using System.Xml;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    public enum ParameterValueType
    {
        [XmlEnum(Name = "0")]
        Conditional,
        [XmlEnum(Name = "1")]
        Static
    }

    public class XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter
    {
        [XmlAttribute(AttributeName = "ParentName")]
        public string ParentName { get; set; }

        [XmlAttribute(AttributeName = "ParameterName")]
        public string ParameterName { get; set; }

        [XmlAttribute(AttributeName = "Label")]
        public string Label { get; set; }

        [XmlAttribute(AttributeName = "Value")]
        public int Value { get; set; }

        [XmlAttribute(AttributeName = "ValueTypeID")]
        public ParameterValueType ValueTypeID { get; set; }

    }
}

用法(选项 1):

string filename = @"C:\Temp\DynamicFormExport.xml";
XmlDynamicFormExport dynamicFormExport = HelperXml.DeserializeXMLFileToObject<XmlDynamicFormExport>(filename);

foreach (var p in dynamicFormExport.DynamicForm.DynamicField.ListParameters.Parameter)
{
    System.Diagnostics.Debug.WriteLine("ParentName: " + p.ParameterName + " p.ValueTypeID: " + p.ValueTypeID.ToString());
}

选项 2:

XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter.cs

using System;
using System.Xml;
using System.Xml.Serialization;

namespace XmlSerializationTest
{
    [Serializable]
    public enum ParameterValueType : int
    {
        [XmlEnum(Name = "Conditional")]
        Conditional = 0,
        [XmlEnum(Name = "Static")]
        Static = 1
    }


    [Serializable()]
    public class XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter
    {
        [XmlAttribute(AttributeName = "ParentName")]
        public string ParentName { get; set; }

        [XmlAttribute(AttributeName = "ParameterName")]
        public string ParameterName { get; set; }

        [XmlAttribute(AttributeName = "Label")]
        public string Label { get; set; }

        [XmlAttribute(AttributeName = "Value")]
        public int Value { get; set; }

        [XmlAttribute(AttributeName = "ValueTypeID")]
        public int ValueTypeID { get; set; }

        //this property isn't written to XML, it's only for use in the app
        [XmlIgnore]
        public ParameterValueType ValueType
        {
            get { return (ParameterValueType)ValueTypeID; }

            set 
            {
                ValueTypeID = (int)value;
            }
        }
    }
}

用法(选项 2):

string filename = @"C:\Temp\DynamicFormExport.xml";
XmlDynamicFormExport dynamicFormExport = HelperXml.DeserializeXMLFileToObject<XmlDynamicFormExport>(filename);

foreach (var p in dynamicFormExport.DynamicForm.DynamicField.ListParameters.Parameter)
{
    System.Diagnostics.Debug.WriteLine("ParentName: " + p.ParameterName + " p.ValueTypeID: " + p.ValueTypeID.ToString() + " p.ValueType: " + p.ValueType.ToString());
}