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

Posted

技术标签:

【中文标题】无法以所需的方式将 XML 属性值解析为 C# 枚举【英文标题】:Unable to parse XML attribute value into C# Enum in a desired way 【发布时间】:2021-10-22 19:11:52 【问题描述】:

我在 C# 中有以下课程


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 是静态的。

我在解析中做错了什么?

【问题讨论】:

变量名不应该是“ID”而不是“Id”吗? [XmlAttribute("ParameterValueType")] ... Parameter ValueTypeID="1" @Naveen 更新,实际上是 ID;我在玩,错误地输入了Id。但是仍然没有得到想要的输出。 @IanKemp,你能详细说明一下代码吗? How do you use XMLSerialize for Enum typed properties in c#? 【参考方案1】:

下面显示了一种使用 System.Xml.Serialization 获取所需属性值的方法。

为反序列化方法创建一个类(名称: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>

为以下各项创建类:

动态表单导出 动态表单 动态场 列表参数 参数

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

DynamicFormExport(名称:XmlDynamicFormExport) DynamicForm(名称:XmlDynamicFormExportDynamicForm) DynamicField(名称:XmlDynamicFormExportDynamicFormDynamicField) ListParameters(名称:XmlDynamicFormExportDynamicFormDynamicFieldListParameters) 参数(名称:XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter

注意:我使用的类名是它上面的类名,前面是类名。 (例如: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 中,但似乎可以存在多个参数,所以我在下面的代码中使用了 List。

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());

【讨论】:

以上是关于无法以所需的方式将 XML 属性值解析为 C# 枚举的主要内容,如果未能解决你的问题,请参考以下文章

Unity c#以所需的日期时间格式将date-string转换为datetime对象

有没有办法以所需的顺序运行Specflow场景(C#Selenium)?

无法将类型“java.lang.String”的属性值转换为属性“事务”所需的类型“java.util.List”

无法将 java.lang.String 类型的属性值转换为所需的 java.time.LocalDateTime 类型

无法将 java.lang.String 类型的属性值转换为所需的 java.util.Date 类型

有没有办法以所需的格式加入这两个表?