无法以所需方式将 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());
}
我在 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());
}