I want to read an XML file with C# (unity project) in order to display some content. the XML file is given by a TALEND Job in Talend Studio.
I've converted an XML file to C# classes and I'm now trying to read this XML (stored in a file) to manage the content.
For the moment, I'm able to read some properties but the most interesting tag are nul. There is no error during the deserialization.
private const string filename = "/Applications/TalendStudio-7.1.1/studio/workspace/LOCAL_PROJECT/process/job1_0.1.item";
void Start()
{
// Create an instance of the XmlSerializer.
XmlSerializer serializer = new XmlSerializer(typeof(Xml2CSharp.ProcessType));
// Declare an object variable of the type to be deserialized.
Xml2CSharp.ProcessType i;
using (Stream reader = new FileStream(filename, FileMode.Open))
{
// Call the Deserialize method to restore the object's state.
i = (Xml2CSharp.ProcessType)serializer.Deserialize(reader);
Debug.Log(i);
}
}
the XML file starts with :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<talendfile:ProcessType
xmlns:talendfile="TalendFile.xsd" xmlns:TalendMapper="http://www.talend.org/mapper" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
defaultContext="Default" jobType="Standard" xmi:version="2.0">
<context confirmationNeeded="false" name="Default">
<contextParameter comment="" name="max_rows" prompt="max_rows?" promptNeeded="false" type="id_Integer" value="10"/>
</context>
<context confirmationNeeded="false" name="prod">
<contextParameter comment="" name="max_rows" prompt="max_rows?" promptNeeded="false" type="id_Integer" value="30"/>
</context>
<context confirmationNeeded="false" name="qa">
<contextParameter comment="" name="max_rows" prompt="max_rows?" promptNeeded="false" type="id_Integer" value="20"/>
</context>
<parameters>
<elementParameter field="TEXT" name="SCREEN_OFFSET_X" show="false" value="0"/>
<elementParameter field="TEXT" name="SCREEN_OFFSET_Y" show="false" value="0"/>
<elementParameter field="TEXT" name="REPOSITORY_CONNECTION_ID" show="false" value=""/>
etc...
the 'context' and 'parameter' are empty. Thank you for your help.
Use xml serialization :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(ProcessType));
ProcessType processType = (ProcessType)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "ProcessType", Namespace = "TalendFile.xsd")]
public class ProcessType
{
[XmlAttribute("defaultContext")]
public string defaultContext { get; set; }
[XmlAttribute("jobType")]
public string jobType { get; set; }
[XmlElement("context", Namespace = "")]
public List<Context> context { get; set; }
[XmlArray("parameters", Namespace = "")]
[XmlArrayItem("elementParameter", Namespace = "")]
public List<Parameters> parameters { get; set; }
}
[XmlRoot("context", Namespace = "")]
public class Context
{
[XmlAttribute("confirmationNeeded")]
public string confirmationNeeded { get; set; }
[XmlAttribute("name")]
public string name { get; set; }
[XmlElement("contextParameter", Namespace = "")]
public ContextParameter contextParameter { get; set; }
}
[XmlRoot("contextParameter", Namespace = "")]
public class ContextParameter
{
[XmlAttribute("comment")]
public string comment { get; set; }
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute("prompt")]
public string prompt { get; set; }
[XmlAttribute("promptNeeded")]
public string promptNeeded { get; set; }
[XmlAttribute("type")]
public string type { get; set; }
[XmlAttribute("value")]
public int value { get; set; }
}
[XmlRoot("parameters", Namespace = "")]
public class Parameters
{
[XmlAttribute("field")]
public string field { get; set; }
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute("show", Namespace = "")]
public string show { get; set; }
private int? _value { get; set; }
[XmlAttribute("value")]
public string value {
get { return _value.ToString(); }
set { _value = value == string.Empty ? (int?)null : int.Parse(value); }
}
}
}
Related
So i've been trying to deserialize this xml file to some objects, its simple enough but it keeps returning null to the objects, the data that i need is stored inside the attributes of the element.
Here is the XML.
<exchangerates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="Valutakurser" author="Danmarks Nationalbank" refcur="DKK" refamt="1">
<dailyrates id="2020-10-20">
<currency code="AUD" desc="Australske dollar" rate="442,98"/>
<currency code="BGN" desc="Bulgarske lev" rate="380,53"/>
</dailyrates>
And this is the deserialisation code.
public static T DeserializeElement<T>(string filename)
{
try
{
T result;
XmlSerializer serializer = new XmlSerializer(typeof(T), new
XmlRootAttribute("exchangerates"));
using (TextReader tr = new StringReader(filename))
{
result = (T)serializer.Deserialize(tr);
}
return result;
}
catch { throw; }
}
And these are the objects
[XmlRoot(Namespace = "http://www.w3.org/2001/XMLSchema-instance",
ElementName = "exchangerates",
DataType = "Valutakurser")]
[Serializable]
public class Valutakurser
{
[XmlArray("dailyrates")]
public DateTime Id { get; set; }
public Currency Currency { get; set; }
}
[Serializable]
public class Currency
{
public string Code { get; set; }
public string Desc { get; set; }
public double Rate { get; set; }
public Currency() { }
}
Currently I keep getting this error and everything returned null:
InvalidOperationException: For non-array types, you may use the following attributes: XmlAttribute, XmlText, XmlElement, or XmlAnyElement
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Valutakurser));
Valutakurser valutakurser = (Valutakurser)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "exchangerates")]
public class Valutakurser
{
[XmlAttribute]
public DateTime id { get; set; }
[XmlElement("dailyrates")]
public DailyRates DalyRates { get; set; }
}
public class DailyRates
{
[XmlElement("currency")]
public List<Currency> Currency { get; set; }
}
public class Currency
{
[XmlAttribute]
public string code { get; set; }
[XmlAttribute]
public string desc { get; set; }
[XmlAttribute]
public double rate { get; set; }
public Currency() { }
}
}
I'm attempting to deserialize an XML file into corresponding C# objects. I've read through the other answers and I'm at a loss as to what I'm doing wrong.
Here's my XML file
<?xml version="1.0" encoding="utf-8"?>
<DialogueObjectCollection>
<DialogueObjects>
<DialogueObject id="0001">
<name>CHARACTER</name>
<dialogue>
<text tag="1">Hi, this is a message.</text>
<text tag="2">Yup.</text>
<text tag="3">What do you want to do?
<options>
<option action= "1">Go back.</option>
<option action="4">Tell me something new.</option>
</options>
</text>
<text tag= "4">This is the end.</text>
</dialogue>
</DialogueObject>
<DialogueObject id="0002">
<name>CHARACTER2</name>
<dialogue>
<text tag="1">Hi.</text>
</dialogue>
</DialogueObject>
</DialogueObjects>
</DialogueObjectCollection>
Here are my classes:
{
[Serializable(), XmlRoot("DialogueObject")]
public class DialogueObject
{
[XmlAttribute("id")]
public string id { get; set; }
[XmlElement("name")]
public string name { get; set; }
[XmlAttribute("tag")]
public int tag { get; set; }
public OptionHolder option;
public DialogueHolder dialogueHolder { get; set; }
[XmlAttribute("action")]
public string action { get; set; }
}
[Serializable(), XmlRoot("dialogue")]
public class DialogueHolder
{
[XmlArray("dialogue")]
[XmlArrayItem("text", IsNullable = false)]
public TextItem[] dialogue { get; set; }
}
[Serializable(),XmlRoot("text")]
public class TextItem
{
[XmlAttribute]
public string tag { get; set; }
public string text { get; set; }
}
[Serializable(),XmlRoot("option")]
public class OptionHolder
{
[XmlAttribute]
public string action;
[XmlElement("option")]
public string option;
}
[Serializable()]
[System.Xml.Serialization.XmlRoot("DialogueObjectCollection")]
public class DialogueObjectCollection
{
[XmlArray("DialogueObjects")]
[XmlArrayItem("DialogueObject", typeof(DialogueObject))]
public DialogueObject[] dialogueObject { get; set; }
}
And my method:
public static void LoadDialogue()
{
DialogueObjectCollection dialogueCollection = null;
string path = "Content/NPCdata.xml";
XmlSerializer serializer = new XmlSerializer(typeof(DialogueObjectCollection));
Console.WriteLine("LOADDINGGGG");
StreamReader reader = new StreamReader(path);
dialogueCollection = (DialogueObjectCollection)serializer.Deserialize(reader);
//test print Console.WriteLine(dialogueCollection.dialogueObject.First().dialogueHolder.dialogue.First().text);
}
So, it's telling me that dialogueHolder is returning null. I can get the dialogueObject.First().name and id to print. I can't figure out why the dialogue text isn't loading into it. (My attempts at fixing it included adding the XmlRootNode attributes and adding more classes-- I'm new to XML serialization in C#)
Thanks for any help!
try code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication3
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
LoadDialogue(FILENAME);
}
public static void LoadDialogue(string path)
{
XmlReader reader = XmlReader.Create(path);
XmlSerializer serializer = new XmlSerializer(typeof(DialogueObjectCollection));
DialogueObjectCollection dialogueObjectCollection = (DialogueObjectCollection)serializer.Deserialize(reader);
}
}
[Serializable(), XmlRoot("DialogueObject")]
public class DialogueObject
{
[XmlAttribute("id")]
public string id { get; set; }
[XmlElement("name")]
public string name { get; set; }
[XmlAttribute("tag")]
public int tag { get; set; }
public OptionHolder option;
[XmlElement("dialogue")]
public DialogueHolder dialogueHolder { get; set; }
[XmlAttribute("action")]
public string action { get; set; }
}
[Serializable(), XmlRoot("dialogue")]
public class DialogueHolder
{
[XmlElement("text")]
public TextItem[] texItem { get; set; }
}
[Serializable(), XmlRoot("text")]
public class TextItem
{
[XmlAttribute]
public string tag { get; set; }
[XmlText()]
public string text { get; set; }
[XmlArray("options")]
[XmlArrayItem("option")]
public OptionHolder[] options { get; set; }
}
[Serializable(), XmlRoot("option")]
public class OptionHolder
{
[XmlAttribute]
public string action;
[XmlElement("option")]
public string option;
}
[XmlRoot("DialogueObjectCollection")]
public class DialogueObjectCollection
{
[XmlArray("DialogueObjects")]
[XmlArrayItem ("DialogueObject")]
public DialogueObject[] dialogueObject { get; set; }
}
}
I have the following class:
[XmlType("supervisor")]
public class Supervisor
{
[XmlAttribute("id")]
public string Id { set; get; }
[XmlElement("Name")]
public string Name { set; get; }
[XmlElement("Contract")]
public int Contracts { set; get; }
[XmlElement("Volume")]
public long Volume { set; get; }
[XmlElement("Average")]
public int Average { set; get; }
}
which reads from XML file:
<digital-sales xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<supervisor id="1236674">
<Name>Hiroki</Name>
<Contract>11</Contract>
<Volume>1036253</Volume>
<Average>94205</Average>
</supervisor>
<supervisor id="123459">
<Name>Ayumi</Name>
<Contract>5</Contract>
<Volume>626038</Volume>
<Average>125208</Average>
</supervisor> ...
</digital-sales>
in the code I create List and process it.
now I want to write the List to XML file while maintaining the
same XML structure. How do I do that?
How to use xml id to fill class object?
Here is the code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication98
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(DigitalSales));
DigitalSales digitalSales = (DigitalSales)serializer.Deserialize(reader);
reader.Close();
XmlWriter writer = XmlWriter.Create(FILENAME);
serializer.Serialize(writer, digitalSales);
}
}
[XmlRoot("digital-sales")]
public class DigitalSales
{
[XmlElement("supervisor")]
public List<Supervisor> supervisor { get; set; }
}
[XmlRoot("supervisor")]
public class Supervisor
{
[XmlAttribute("id")]
public string Id { set; get; }
[XmlElement("Name")]
public string Name { set; get; }
[XmlElement("Contract")]
public int Contracts { set; get; }
[XmlElement("Volume")]
public long Volume { set; get; }
[XmlElement("Average")]
public int Average { set; get; }
}
}
I have XML:
<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time='2015-12-16'>
<Cube currency='USD' rate='1.0933'/>
<Cube currency='JPY' rate='133.18'/>
</Cube>
</Cube>
</gesmes:Envelope>
which I'm trying to deserialize with:
[XmlRoot("Envelope", Namespace = EcbNameSpace)]
public class EcbEnvelope
{
const string EcbNameSpace = "http://www.gesmes.org/xml/2002-08-01";
[XmlElement("Sender", Namespace = EcbNameSpace)]
public string EcbSender { get; set; }
[XmlElement("subject", Namespace = EcbNameSpace)]
public string EcbSubject { get; set; }
[XmlArray("Cube")]
[XmlArrayItem("Cube")]
public List<CubeRoot> CubeRootEl { get; set; }
public class CubeRoot
{
[XmlAttribute("time")]
public string Time { get; set; }
[XmlElement("Cube")]
public List<CubeItem> CubeItems { get; set; }
public class CubeItem
{
[XmlAttribute("rate")]
public string RateStr { get; set; }
[XmlIgnore]
public decimal Rate
{
get { return decimal.Parse(RateStr); }
}
[XmlAttribute("currency")]
public string Currency { get; set; }
}
}
}
However, it deserializes CubeRootEl as empty list. If I remove namspaces from XML, then it deserializes successfully. What am I doing wrong? I tried adding empty namespaces to CubeRootEl in code, but also unsuccessfully.
Here's the code used for deserialization:
var serializer = new XmlSerializer(typeof(EcbEnvelope));
using (var streamReader = new StreamReader(pathToFile))
var a = serializer.Deserialize(streamReader) as EcbEnvelope;
}
You have a few issues:
You do not specify a namespace for the property public List<CubeRoot> CubeRootEl. When a namespace for a property is not specified, XmlSerializer assumes it to be in the same namespace as the containing element, which would in this case be "http://www.gesmes.org/xml/2002-08-01". But the <Cube> elements are not in this namespace since they do not have the "gesmes:" prefix.
Your XML has a default namespace declaration xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref". Thus the <Cube> elements are actually in this namespace.
Sender is not a simple string-valued element, it has a nested element <gesmes:name>European Central Bank</gesmes:name>.
Fixing these three issues allows your XML to be deserialized:
[XmlRoot("Envelope", Namespace = GesmesNameSpace)]
public class EcbEnvelope
{
public const string GesmesNameSpace = "http://www.gesmes.org/xml/2002-08-01";
public const string EcbNameSpace = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref";
[XmlElement("Sender", Namespace = GesmesNameSpace)]
public EcbSender Sender { get; set; }
[XmlElement("subject", Namespace = GesmesNameSpace)]
public string EcbSubject { get; set; }
[XmlArray("Cube", Namespace = EcbNameSpace)]
[XmlArrayItem("Cube")]
public List<CubeRoot> CubeRootEl { get; set; }
public class EcbSender
{
[XmlElement("name")]
public string Name { get; set; }
}
public class CubeRoot
{
[XmlAttribute("time")]
public string Time { get; set; }
[XmlElement("Cube")]
public List<CubeItem> CubeItems { get; set; }
public class CubeItem
{
[XmlAttribute("rate")]
public string RateStr { get; set; }
[XmlIgnore]
public decimal Rate
{
get { return decimal.Parse(RateStr); }
}
[XmlAttribute("currency")]
public string Currency { get; set; }
}
}
}
Data ("1.0.0") from attribute "version" fall into property. But the property "Event" in the same class remains empty.
If cut namespace from XML, it will work.
My XML:
<rootnode>
<ns:eventresponse xmlns:ns="somenamespace" version="1.0.0">
<event id="694717028">
<somedata>val</somedata>
</event>
</ns:eventresponse>
</rootnode>
My class:
[XmlRoot("rootnode")]
public class RootNode
{
[XmlElement(ElementName = "eventresponse", Namespace = "somenamespace")]
public EventResponseData EventResponse { get; set; }
}
public class EventResponseData
{
[XmlElement("event")]
public EventData Event { get; set; }
[XmlAttribute("version")]
public string Version { get; set; }
}
public class TvEventData
{
[XmlAttribute("id")]
public string EventID { get; set; }
[XmlElement("somedata")]
public string SomeData { get; set; }
}
My Deserializer:
using (var reader = XmlReader.Create(new StringReader(xml)))
{
reader.MoveToContent();
var obj = (T)new XmlSerializer(typeof(T)).Deserialize(reader);
}
Your event element is implicitly in the same namespace in the XML due to namespace defaulting, so you should specify that in your declaration:
public class EventResponseData
{
[XmlElement(ElementName = "event", Namespace = "somenamespace")]
public EventData Event { get; set; }
[XmlAttribute("version")]
public string Version { get; set; }
}