-1

I have the following class in 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; }
}

Then I have the following Enum,


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

I am trying to parse the following 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>

I am using the below code to parse 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;
        }

What I see in the debugger is that, I get ValueTypeID = Conditional even though XML I am parsing has ValueTypeID = 1, I expect my ValueTypeID to be Static.

What am I doing wrong with the parsing?

8
  • Shouldnt variable name be "ID" instead of "Id"? Commented Aug 21, 2021 at 18:14
  • [XmlAttribute("ParameterValueType")] ... Parameter ValueTypeID="1" Commented Aug 21, 2021 at 18:25
  • @Naveen Updated, it's actually ID; I was playing around and mistakenly put Id. Still not getting the desired output, though. Commented Aug 21, 2021 at 18:48
  • @IanKemp, Could you please elaborate on Code? Commented Aug 21, 2021 at 18:50
  • How do you use XMLSerialize for Enum typed properties in c#? Commented Aug 21, 2021 at 18:55

1 Answer 1

2

Below shows one way to get the desired attribute values by using System.Xml.Serialization.

Create a class (name: HelperXml.cs) for the deserialize method.

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

Given the following 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>

Create classes for each of the following:

  • DynamicFormExport
  • DynamicForm
  • DynamicField
  • ListParameters
  • Parameter

As far as naming strategy, in order to keep the classes in the desired order in VS, it can be helpful to do something like the following:

  • DynamicFormExport (name: XmlDynamicFormExport)
  • DynamicForm (name: XmlDynamicFormExportDynamicForm)
  • DynamicField (name: XmlDynamicFormExportDynamicFormDynamicField)
  • ListParameters (name: XmlDynamicFormExportDynamicFormDynamicFieldListParameters)
  • Parameter (name: XmlDynamicFormExportDynamicFormDynamicFieldListParametersParameter)

Note: The class names I used is the class name above it pre-pended to the class name. (ex: XmlDynamicFormExport + DynamicForm = XmlDynamicFormExportDynamicForm). Although, the names in your XML are somewhat long, so a different naming strategy may be desirable.

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

Note: Although it wasn't shown in the XML in the OP, it seems like more than 1 parameter could exist, so I used a List in the code below.

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

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

    }
}

Usage (Option 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());
}

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

Usage (Option 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());
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.