Click here to Skip to main content
13,192,855 members (53,972 online)
Rate this:
 
Please Sign up or sign in to 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 19-May-17 8:51am
Updated 20-May-17 5:51am

1 solution

Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

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

[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

 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

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

[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

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

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy |
Web02 | 2.8.171017.2 | Last Updated 20 May 2017
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100