I have the following XML sample that I want to read the data. I only provided one "project" element but this can have many "project" inside the "projects" root.
<?xml version="1.0" encoding="utf-8"?>
<projects>
<project>
<details>
<projectName><![CDATA[CxWtGZxYT]]></projectName>
<uniqueID>Pt144</uniqueID>
<collaboratingList>
<collaboratingOrganisation id="5318" value="EpCyxCv RvGxrXAYXGpA xCxWtGZxYT"/>
<collaboratingOrganisation id="0000" value="EpCyxCv RvGxrXAYXGpA xCxWtGZxYTd"/>
</collaboratingList>
<researchOutputList>
<item>
<pubDate>2014-02-04T00:00:00+00:00</pubDate>
<title><![CDATA[rGDEZ]]></title>
<link>link</link>
<guid>guid</guid>
<description><![CDATA[uGDB BDstA rGDEZ]]></description>
</item>
<item>
<pubDate>2015-08-04T00:00:00+00:00</pubDate>
<title><![CDATA[AERx CApCYZ.]]></title>
<link>link</link>
<guid>guid</guid>
<description><![CDATA[vwtpY]]></description>
</item>
</researchOutputList>
</details>
</project>
</projects>
I can read the <projectName> and <uniqueId> but cannot <researchOutputList> and <collaboratingList>. I am not sure what I am missing or if my XML structure is correct. My codes below:
[Serializable]
[XmlRoot("projects")]
public class BulkProjectRoot
{
public BulkProjectRoot()
{
BulkProjectDetails = new List<BulkProjectData>();
}
[XmlArray("project")]
[XmlArrayItem("details")]
public List<BulkProjectData> BulkProjectDetails { get; set; }
}
[Serializable]
[XmlRoot("details")]
public class BulkProjectData
{
public BulkProjectData()
{
ProjectResearches = new List<ProjectResearchOutputs>();
}
[XmlElement("projectName")]
public string Name { get; set; }
[XmlElement("uniqueID")]
public string ProjectUniqueId { get; set; }
[XmlElement("researchOutputList")]
public List<ProjectResearchOutputs> ProjectResearches { get; set; }
}
[Serializable]
[XmlRoot("researchOutputList")]
public class ProjectResearchOutputs
{
public ProjectResearchOutputs()
{
ResearchItemsList = new List<ResearchOutputItems>();
}
[XmlElement("item")]
public List<ResearchOutputItems> ResearchItemsList { get; set; }
}
[Serializable]
[XmlRoot("item")]
public class ResearchOutputItems
{
[XmlElement("pubDate")]
public DateTime? PublishDate { get; set; }
[XmlElement("title")]
public string ResearchTitle { get; set; }
[XmlElement("link")]
public string ResearchLink { get; set; }
[XmlElement("guid")]
public string ResearchGuid { get; set; }
[XmlElement("description")]
public string ResearchDescription { get; set; }
}
The reasearchlist deserializes fine with Linqpad, but you are missing the collaboration information in your BulkProjectData class.
void Main()
{
var xml = #"<?xml version=""1.0"" encoding=""utf - 8""?>
<projects>
<project>
<details>
<projectName><![CDATA[CxWtGZxYT]]></projectName>
<uniqueID> Pt144 </uniqueID>
<collaboratingList>
<collaboratingOrganisation id = ""5318"" value = ""EpCyxCv RvGxrXAYXGpA xCxWtGZxYT"" />
<collaboratingOrganisation id = ""0000"" value = ""EpCyxCv RvGxrXAYXGpA xCxWtGZxYTd"" />
</collaboratingList>
<researchOutputList>
<item>
<pubDate>2014-02-04T00:00:00+00:00</pubDate>
<title><![CDATA[rGDEZ]]></title>
<link> link </link>
<guid> guid </guid>
<description><![CDATA[uGDB BDstA rGDEZ]]></description>
</item>
<item>
<pubDate>2015-08-04T00:00:00+00:00</pubDate>
<title><![CDATA[AERx CApCYZ.]]></title>
<link> link </link>
<guid> guid </guid>
<description><![CDATA[vwtpY]]></description>
</item>
</researchOutputList>
</details>
</project>
</projects>";
var serializer = new XmlSerializer(typeof(BulkProjectRoot));
var result = (BulkProjectRoot)serializer.Deserialize(new StringReader(xml));
result.Dump();
Jsut make this change -
[Serializable]
[XmlRoot("details")]
public class BulkProjectData
{
public BulkProjectData()
{
// Not a list
ProjectResearches = new ProjectResearchOutputs();
}
[XmlElement("projectName")]
public string Name { get; set; }
[XmlElement("uniqueID")]
public string ProjectUniqueId { get; set; }
[XmlElement("researchOutputList")]
public ProjectResearchOutputs ProjectResearches { get; set; }
}
Related
I'm currently working on a .NET 4.6 console application. I need to parse a nested XML from an URL and transform the XML into an object list.
The URL for the sample XML is the following:
https://www.w3schools.com/xml/cd_catalog.xml
The XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
</CATALOG>
My corresponding C# classes look like this:
[XmlRoot(ElementName = "CATALOG")]
public class Catalog
{
[XmlElement("CD")]
List<Cd> Cds { get; set; }
}
[XmlRoot(ElementName = "CD")]
public class Cd
{
[XmlElement("TITLE")]
public string Title { get; set; }
[XmlElement("ARTIST")]
public string Artist { get; set; }
[XmlElement("COUNTRY")]
public string Country { get; set; }
[XmlElement("COMPANY")]
public string Company { get; set; }
[XmlElement("PRICE")]
public double Price { get; set; }
[XmlElement("YEAR")]
public int Year { get; set; }
}
My program class looks like this:
class Program
{
static void Main(string[] args)
{
Init();
}
public static void Init() {
var url = "https://www.w3schools.com/xml/cd_catalog.xml";
XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument.Load(url);
var catalog = myXmlDocument.InnerXml.ToString();
var result = Deserialize<Catalog>(catalog);
// result is null :(
Console.ReadKey();
}
public static T Deserialize<T>(string xmlText)
{
try
{
var stringReader = new StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch (Exception ex)
{
throw;
}
}
}
So far so good, my variable catalog consists out of an XML string, but somehow the XML doesn't get parsed correctly. I always get null as a return result. Perhaps it's because of my class definitions.
What do you think, do you have an idea on how to solve this issue? To retrieve an List<Cd> instead of null.
The error is very subtle. You have done everything right, but you missed to add the public access qualifier in your Catalog class, on the list of Cd like so:
[XmlRoot(ElementName = "CATALOG")]
public class Catalog
{
[XmlElement("CD")]
public List<Cd> Cds { get; set; }
}
Since the access qualifiers default to private, the deserializer is having a hard time finding the correct property to deserialize the XML into.
List<Cd> Cds { get; set; }
Change this line to
Public List<Cd> Cds { get; set; }
I am c# silverlight beginner i am under a situation that i have thios xml code:
string xmlstring = #"<?xml version='1.0' encoding='utf-8' ?>
<par>
<name>amount</name>
<label>Amount</label>
<unit>Hundred</unit >
<comp>
<type>Combo</type>
<attributes>
<type>Integer</type>
<displayed>4</displayed>
<selected>0</selected>
<item>5</item>
</attributes>
</comp>
</par>";
** Now what is the problem ?**
In the last line when i try to debug "item" which is asssigned several value like 5 on line Debug.WriteLine(attrib.item);i just see only "5" on debugging it dont show other values. I guess i need to implement a list for it. But how to do it here that i don't know. Could some one please help me so that i will be able to have all the assigned values to item in this c# code because after this step i havce to create a GUI of it. Woudl be a big help.
Note: I cannot use ArrayList because silverligth dont support it any other lastertnative please ?
This is what you need:
[XmlRoot(ElementName = "parameter")]
public class Parameter
{
[XmlElement("name")]
public string Name { get; set; }
[XmlElement("label")]
public string Label { get; set; }
[XmlElement("unit")]
public string Unit { get; set; }
[XmlElement("component")]
public Component Component { get; set; }
}
[XmlRoot(ElementName = "component")]
public class Component {
[XmlElement("type")]
public string Type { get; set; }
[XmlElement("attributes")]
public Attributes Attributes { get; set; }
}
[XmlRoot(ElementName = "attributes")]
public class Attributes
{
[XmlElement("type")]
public string Type { get; set; }
[XmlElement("displayed")]
public string Displayed { get; set; }
[XmlElement("selected")]
public string Selected { get; set; }
[XmlArray("items")]
[XmlArrayItem("item", typeof(string))]
public List<string> Items { get; set; }
}
class Program
{
static void Main(string[] args)
{
string xmlstring = #"<?xml version='1.0' encoding='utf-8' ?>
<parameter>
<name>max_amount</name>
<label>Max Amount</label>
<unit>Millions</unit>
<component>
<type>Combo</type>
<attributes>
<type>Integer</type>
<displayed>4</displayed>
<selected>0</selected>
<items>
<item>5</item>
<item>10</item>
<item>20</item>
<item>50</item>
</items>
</attributes>
</component >
</parameter>";
XmlSerializer deserializer = new XmlSerializer(typeof(Parameter));
XmlReader reader = XmlReader.Create(new StringReader(xmlstring));
Parameter parameter = (Parameter)deserializer.Deserialize(reader);
Console.WriteLine("Type: {0}", parameter.Component.Attributes.Type);
Console.WriteLine("Displayed: {0}", parameter.Component.Attributes.Displayed);
Console.WriteLine("Selected: {0}", parameter.Component.Attributes.Selected);
Console.WriteLine("Items: ");
foreach (var item in parameter.Component.Attributes.Items)
{
Console.WriteLine("\t{0}", item);
}
Console.ReadLine();
}
}
Note small change in xmlstring, now every <item></item> is inside container:
<items>
<item>5</item>
<item>10</item>
<item>20</item>
<item>50</item>
</items>
I have an XML document provided to me externally that I need to import into my application. The document is badly written, but not something I can really do much about.
<?xml version="1.0" encoding="iso-8859-1"?>
<xml>
<Items>
<Property1 />
<Property2 />
...
</Items>
<Items>
<Property1 />
<Property2 />
...
</Items>
...
</xml>
How should I go about using the XmlSerializer for this?
It doesn't seem to matter what class setup I use, or wether I put XmlRoot(ElementName="xml") on my base class it always says that the <xml xmlns=''> is unexpected.
Edit: Added the C# code I am using
[XmlRoot(ElementName = "xml")]
public class Container
{
public List<Items> Items { get; set; }
}
public class Items
{
public short S1 { get; set; }
public short S2 { get; set; }
public short S3 { get; set; }
public short S4 { get; set; }
public short S5 { get; set; }
public short S6 { get; set; }
public short S7 { get; set; }
}
public class XMLImport
{
public Container Data{ get; private set; }
public static XMLImport DeSerializeFromFile(string fileName)
{
XMLImport import = new XMLImport();
XmlSerializer serializer = new XmlSerializer(typeof(Container));
using (StreamReader reader = new StreamReader(fileName))
import.Data = (Container)serializer.Deserialize(reader);
return import;
}
}
Say you have a class Items maps to each <Items> node:
public class Items
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
You can deserialize your list of Items like this:
var doc = XDocument.Parse(
#"<?xml version=""1.0"" encoding=""iso-8859-1""?>
<xml>
<Items>
<Property1 />
<Property2 />
</Items>
<Items>
<Property1 />
<Property2 />
</Items>
</xml>");
var serializer = new XmlSerializer(typeof(List<Items>), new XmlRootAttribute("xml"));
List<Items> list = (List<Items>)serializer.Deserialize(doc.CreateReader());
The root of your XML is not a List, the root of your xml is the <xml> node I think you are just confused by its name :)
please visit the following link, It has many good answers voted by many people.
Here is the link: How to Deserialize XML document
Error Deserializing Xml to Object - xmlns='' was not expected
Simply take off the Namespace =:
[XmlRoot("xml"), XmlType("xml")]
public class RegisterAccountResponse {...}
I try to deserialize xml file:
<?xml version="1.0" encoding="utf-8"?>
<XmlFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<OBJECTS ITEM="ItemValue" TABLE_NAME="TableExample">
</OBJECTS>
</XmlFile>
My deserialize class code looks like that:
[Serializable]
[XmlRoot("XmlFile")]
public class SerializeObject
{
[XmlAttribute("ITEM")]
public string Item { get; set; }
[XmlAttribute("TABLE_NAME")]
public string Table_Name { get; set; }
}
When I try deserialize xml file i always got no errors and Item and Table_Name equals null. Why?
Thx for replay
[XmlRoot("XmlFile")]
public class SerializableContainer
{
[XmlElement("OBJECTS")]
public SerializeObject[] Objects { get; set; }
}
public class SerializeObject
{
[XmlAttribute("ITEM")]
public string Item { get; set; }
[XmlAttribute("TABLE_NAME")]
public string Table_Name { get; set; }
}
And then you deserialize with:
var serializer = new XmlSerializer(typeof(SerializableContainer));
using (var file = File.OpenText("sample.xml"))
{
var data = (SerializableContainer)serializer.Deserialize(file);
// ...
}
leaving here a more complete example in case anyone needs: http://davidsonsousa.net/en/post/serializedeserialize-objects-to-xml-with-c
Cheers!
I'm trying to deserialize an XML file to an object array, but I'm receiving empty objects.
My question looks similar to this: How to Deserialize xml to an array of objects? but I can't seem to create a class which inherits IXmlSerializable. That said, I don't think that approach is necessary.
Am I doing something wrong?
File Object
[XmlType("file")]
public class File
{
[XmlElement("id")]
public string Id { get; set; }
[XmlElement("company_name")]
public string Company_Name { get; set; }
[XmlElement("docs")]
public HashSet<doc> Docs { get; set; }
}
Doc Object
[XmlType("doc")]
public class Doc
{
[XmlElement("valA")]
public string ValA { get; set; }
[XmlElement("valB")]
public string ValB { get; set; }
}
XML
<?xml version="1.0" encoding="UTF-8"?>
<files>
<file>
<id>12345</id>
<company_name>Apple</company_name>
<docs>
<doc>
<valA>Info</valA>
<valB>More Info</valB>
</doc>
</docs>
</file>
<file>
<id>12345</id>
<company_name>Microsoft</company_name>
<docs>
<doc>
<valA>Even More Info</valA>
<valB>Lots of it</valB>
</doc>
</docs>
</file>
</files>
Deserialization code
XmlSerializer mySerializer = new XmlSerializer(typeof(File[]), new XmlRootAttribute("files"));
using (FileStream myFileStream = new FileStream("Files.xml", FileMode.Open))
{
File[] r;
r = (File[])mySerializer.Deserialize(myFileStream);
}
You have decorated your properties with XMLAttribute but they are elements in your XML. So, change all XMLAttribute to XmlElement.
[XmlType("file")]
public class File
{
[XmlElement("id")]
public string Id { get; set; }
[XmlElement("company_name")]
public string Company_Id { get; set; }
[XmlArray("docs")]
public HashSet<Doc> Docs { get; set; }
}
[XmlType("doc")]
public class Doc
{
[XmlElement("valA")]
public string ValA { get; set; }
[XmlElement("valB")]
public string ValB { get; set; }
}
Also you XML is not well formed. I guess this is typo though -
<company_name>Apple</company_id>
<company_name>Microsoft</company_id>
Ending tag should be company_name -
<company_name>Apple</company_name>
<company_name>Microsoft</company_name>
I would use xml parser..
XDocument doc=XDocument.Load(url);
File[] r=doc.Elements("file")
.Select(f=>
new File
{
Id=f.Element("id").Value,
Company_Id=f.Element("company_name").Value,
Docs=new HashSet<Docs>(
f.Elements("docs")
.Elements("doc")
.Select(d=>
new Doc
{
ValA=d.Element("valA").Value,
ValB=d.Element("valB").Value
}))
}).ToArray();