Click here to Skip to main content
15,880,608 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have XML data which I wants to convert into the C# object properties. I have tried deserializing, but its not separating out name and value in to the properties.

XML Sample:

<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<fields>
<field name="Company Name">
<value>ABC

<field name="Company Address">
<value>Chicago

<field name="Company phone">
<value>123-456-7894

<field name="ACSysHP_ASHP_135k_240k_MeasureID">
<value>2635




What I have tried:

This is my Main Class:

mespace TestApp
{
    [XmlTypeAttribute]
    [XmlRootAttribute("xfdf", Namespace = "http://ns.adobe.com/xfdf/")]
    public class XFDF
    {
        [XmlElementAttribute("fields")]
        public Fields fields { get; set; }
    }

    public class Fields
    {
        public Fields()
        {
            field = new List<Field>();
        }
        [XmlElement(ElementName = "field")]
        public List<Field> field { get; set; }
        
    }

    [XmlRoot(ElementName = "field")]
    // [XmlTypeAttribute]
    public class Field
    {
        // "Company City"

        [XmlAttribute("name")]
        public string Name { get; set; }

        [XmlElementAttribute("value")]
        public string value { get; set; }

    }
}




This is form Code:

private void button1_Click(object sender, EventArgs e)
        {

            string path = string.Empty;

            path = Directory.GetCurrentDirectory() + @"\XML\Application 1-16-17_data_030617.xml";

            string xData = File.ReadAllText(path);

            var deserializer = new XmlSerializer(typeof(XFDF));
            using (var reader = XmlReader.Create(new StringReader(xData)))
            {
                XFDF test = (XFDF)deserializer.Deserialize(reader);
               // MessageBox.Show("Field Name: " + test.fields[0].field[1885].Name + Environment.NewLine + " value:" + test.fields[0].field[1885].value);
            }
                


        }



It gives you result as:
Field Name: Company Name
value: ABC
Field Name: Company Address
value: Chicago

Currently my class has sub class called Field and it has 2 properties Name and Value: What I want in is in as to have a property called CompanyName and when I call that property from Form1, I should give me "ABC".
Posted
Updated 20-May-17 5:51am

1 solution

I'm not sure if its a result of bad formatting but your code and XML has quite a few issues. The XML is malformed, correctly formatted would be

XML
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
	<fields>
		<field name="Company Name">
			<value>ABC</value>
		</field>
		<field name="Company Address">
			<value>Chicago</value>
		</field>
		<field name="Company phone">
			<value>123-456-7894</value>
		</field>
		<field name="ACSysHP_ASHP_135k_240k_MeasureID">
			<value>2635</value>
		</field>
	</fields>
</xfdf>


And if you are serializing, the correct class structure/notation would be the following (Note: I used Xml2CSharp.com | Convert your XML Examples into XmlSerializer compatable C# Classes[^] to convert the XML to c# classes for me)

C#
[XmlRoot(ElementName="field", Namespace="http://ns.adobe.com/xfdf/")]
public class Field {
	[XmlElement(ElementName="value", Namespace="http://ns.adobe.com/xfdf/")]
	public string Value { get; set; }
	[XmlAttribute(AttributeName="name")]
	public string Name { get; set; }
}

[XmlRoot(ElementName="fields", Namespace="http://ns.adobe.com/xfdf/")]
public class Fields {
	[XmlElement(ElementName="field", Namespace="http://ns.adobe.com/xfdf/")]
	public List<Field> Field { get; set; }
}

[XmlRoot(ElementName="xfdf", Namespace="http://ns.adobe.com/xfdf/")]
public class Xfdf {
	[XmlElement(ElementName="fields", Namespace="http://ns.adobe.com/xfdf/")]
	public Fields Fields { get; set; }
	[XmlAttribute(AttributeName="xmlns")]
	public string Xmlns { get; set; }
	[XmlAttribute(AttributeName="space", Namespace="http://www.w3.org/XML/1998/namespace")]
	public string Space { get; set; }
}


Then to deserialize your XML to C# objects you'd do

C#
var stream = new MemoryStream();
           var writer = new StreamWriter(stream);
           writer.Write(xml);
           writer.Flush();
           stream.Position = 0;

           var reader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
           var myXmlObject = new XmlSerializer(typeof(Xfdf)).Deserialize(reader) as Xfdf;



So once you've desrialized your code, you can loop over it like so

C#
foreach (var item in myXmlObject.Fields.Field)
            {
                Console.WriteLine("Field Name {0} - Field Value {1}", item.Name, item.Value);
            }



Which provides the output

Quote:
Field Name Company Name - Field Value ABC
Field Name Company Address - Field Value Chicago
Field Name Company phone - Field Value 123-456-7894
Field Name ACSysHP_ASHP_135k_240k_MeasureID - Field Value 2635



EDIT:

Altered XML to support new field/property names

XML
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
	<fields>
		<field>
			<CompanyName>ABC</CompanyName>
			<CompanyPhoneNumber>ABC</CompanyPhoneNumber>
			<CompanyAddress>ABC</CompanyAddress>
		</field>
		<field>
			<CompanyName>ABC</CompanyName>
			<CompanyPhoneNumber>ABC</CompanyPhoneNumber>
			<CompanyAddress>ABC</CompanyAddress>
		</field>
		<field>
			<CompanyName>ABC</CompanyName>
			<CompanyPhoneNumber>ABC</CompanyPhoneNumber>
			<CompanyAddress>ABC</CompanyAddress>
		</field>
		<field>
			<CompanyName>ABC</CompanyName>
			<CompanyPhoneNumber>ABC</CompanyPhoneNumber>
			<CompanyAddress>ABC</CompanyAddress>
		</field>
	</fields>
</xfdf>


Altered Field class for serialization

C#
[XmlRoot(ElementName="field", Namespace="http://ns.adobe.com/xfdf/")]
public class Field {
	[XmlElement(ElementName="CompanyName", Namespace="http://ns.adobe.com/xfdf/")]
	public string CompanyName { get; set; }
	[XmlElement(ElementName="CompanyPhoneNumber", Namespace="http://ns.adobe.com/xfdf/")]
	public string CompanyPhoneNumber { get; set; }
	[XmlElement(ElementName="CompanyAddress", Namespace="http://ns.adobe.com/xfdf/")]
	public string CompanyAddress { get; set; }
}


Which would then allow you to do

C#
foreach (var item in myXmlObject.Fields.Field)
{
	Console.WriteLine("CompanyName: {0}", item.CompanyName);
	Console.WriteLine("CompanyAddress: {0}", item.CompanyAddress);
	Console.WriteLine("CompanyPhoneNumber: {0}", item.CompanyPhoneNumber);
}
 
Share this answer
 
v3
Comments
Sr.SoftwareDev 19-May-17 16:39pm    
Yes XML is formatted wrong here, I have correct format. The issue is in the Field class I want properties called CompanyName, companyAddress, CompanyPhone. Which should give me value of those properties(field name). For example in your code I want Item.Companyname and should return me
ABC.
David_Wimbley 19-May-17 17:25pm    
I've updated my response. You have a few options to do what you are wanting in your XML. I'm not sure if you are just learning or not so I didn't take great care in formatting the XML how I would prefer it but if your goal is to keep your original formatting of the Field element with one child element of Value, then you'll need to change the XML i updated from elements to attributes of field and also change the C# class to behave like the name property.

But based on what i understand you wanting to do, the above edit should accomplish that.
Sr.SoftwareDev 19-May-17 17:30pm    
I can not change the format of XML, as I receive this format from the customer. I have to use this format of XML and have to parse in to the object with properties. I tried every possible things, I think I can not just do it in to the properties it self. I have to go by Name and Value itself.

Thank you for your response.
David_Wimbley 19-May-17 18:01pm    
Then i would say you need to expand upon this first option. You'd do create your own class to be in the format you need it and then serialize the XML to the C# classes above but then you assign those values to your custom class.

Ex:


var myData = new List<ProperFormattedXmlClass>();


foreach(var item in myXmlObject.Fields.Field)
{
    var data = new ProperFormattedXmlClass();
    if(item.Name == "Company Name")
    {
       //Assign  company name value here to .CompanyName from my class
       data.CompanyName = item.Value;
    }
}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900