I am looking into loading a large number of InfoPath XML files into Cosmos DB as Json files to test a possible project. But I am struggling with converting the XML files to Json and then loading back into a c# class. I think this is related to the namespace that InfoPath puts into the XML but I'm not sure. I thought at first I should try to remove all the namespace references from the XML but now I'm wondering if I just need to work more on the definition of the class file. To generate the class file I used Visual Studio "paste as Json". I assumed after loading the XML, saving to Json, then using that as the basis for the new class file, I could load right back into the object but when I call DeserializeObject it always ends up null.
Is this because the class file definition needs to be changed or should I instead look to try and clean the XML prior to converting to Json?
Sample XML
<?xml version="1.0" encoding="utf-8"?>
<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:myProject:-myXSD-2017-05-05T14-19-13" solutionVersion="1.0.0.2046" productVersion="16.0.0.0" PIVersion="1.0.0.0" href="https://myportal.sharepoint.com/sites/mySite/myProject/Forms/template.xsn"?>
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.4"?>
<?mso-infoPath-file-attachment-present?>
<my:myFields xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2017-05-05T14:19:13" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls" xmlns:ma="http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes" xmlns:d="http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields" xmlns:q="http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types" xmlns:tns="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xml:lang="en-US">
<my:Admin>
<my:Routing_Order>
<my:Approver-1_Order>1</my:Approver-1_Order>
<my:Approver-2_Order>5</my:Approver-2_Order>
<my:Approver-3_Order>4</my:Approver-3_Order>
</my:Routing_Order>
</my:Admin>
<my:Request_Status>Save as Draft</my:Request_Status>
<my:Request_Type>CAPEX</my:Request_Type>
</my:myFields>
Class file
namespace xml_to_json
{
public class Rootobject
{
public MyMyfields mymyFields { get; set; }
}
public class MyMyfields
{
public string xmlnsmy { get; set; }
public string xmlnsxsi { get; set; }
public string xmlnsxhtml { get; set; }
public string xmlnspc { get; set; }
public string xmlnsma { get; set; }
public string xmlnsd { get; set; }
public string xmlnsq { get; set; }
public string xmlnsdfs { get; set; }
public string xmlnsdms { get; set; }
public string xmlnstns { get; set; }
public string xmlnss1 { get; set; }
public string xmlnshttp { get; set; }
public string xmlnstm { get; set; }
public string xmlnssoap { get; set; }
public string xmlnssoapenc { get; set; }
public string xmlnsmime { get; set; }
public string xmlnssoap12 { get; set; }
public string xmlnswsdl { get; set; }
public string xmlnsxd { get; set; }
public string xmllang { get; set; }
public MyAdmin myAdmin { get; set; }
public string myRequest_Status { get; set; }
public string myRequest_Type { get; set; }
}
public class MyAdmin
{
public MyRouting_Order myRouting_Order { get; set; }
}
public class MyRouting_Order
{
public string myApprover1_Order { get; set; }
public string myApprover2_Order { get; set; }
public string myApprover3_Order { get; set; }
}
}
Console test code
namespace xml_to_json
{
class Program
{
static void Main(string[] args)
{
XmlDocument myDoc = new XmlDocument();
string sourcedir = #"C:\Users\mystuff\Downloads\test-clean\";
string xmlfilein = #"test";
string xmlfile = string.Concat(sourcedir, xmlfilein, ".xml");
string jsonfileout = string.Concat(sourcedir, xmlfilein, ".json");
myDoc.Load(xmlfile);
string jsonText = JsonConvert.SerializeXmlNode(myDoc.LastChild);
File.WriteAllText(jsonfileout, jsonText);
Rootobject obj = new Rootobject();
obj = JsonConvert.DeserializeObject<Rootobject>(jsonText);
Console.WriteLine(obj.mymyFields.myRequest_Status);
}
}
}
Try code below using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement routingOrder = doc.Descendants().Where(x => x.Name.LocalName == "Routing_Order").FirstOrDefault();
Dictionary<string, string> orders = routingOrder.Elements()
.GroupBy(x => x.Name.LocalName, y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
string status = (string)doc.Descendants().Where(x => x.Name.LocalName == "Request_Status").FirstOrDefault();
string requestType = (string)doc.Descendants().Where(x => x.Name.LocalName == "Request_Type").FirstOrDefault();
}
}
}
Using suggestion from jdweng and XDocument helped to clean the XML file for easier transition to Json. Below is a sample of code I used to clean the document.
XDocument newxdoc = XDocument.Load(xmlfile);
newxdoc.DescendantNodes().Where(e => e.NodeType.ToString().StartsWith("ProcessingInstruction")).Remove();
string newstringdoc = RemoveAllNamespaces(newxdoc.ToString());
newxdoc = XDocument.Parse(newstringdoc);
Related
I'm following the tutorial given here for deserializing an embedded xml document.
My Xml doc:
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfAgency xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DbAgencyDefinition>
<Name>RTD</Name>
<Country>USA</Country>
<City>Denver</City>
<State>CO</State>
<GtfsZipUrlDirectory>http://www.address.com/etc/</GtfsZipUrlDirectory>
<GtfsZipUrlFileName>file_name.zip</GtfsZipUrlFileName>
</DbAgencyDefinition>
</ArrayOfAgency>
My class I'm deserializing to:
public class DbAgencyDefinition
{
public string Name { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string GtfsZipUrlDirectory { get; set; }
public string GtfsZipUrlFileName { get; set; }
public string State { get; set; }
}
The code that's trying to deserialize the XML to a list of DbAgencyDefinition:
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(DbAgencyDefinition)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MyNamespace.Resources.xml.AgencyDefinitions.xml");
var agencies = new List<DbAgencyDefinition>();
using (var reader = new StreamReader(stream))
{
var serializer = new XmlSerializer(typeof(List<DbAgencyDefinition>));
agencies = (List<DbAgencyDefinition>)serializer.Deserialize(reader);
}
The error I'm getting is:
System.Exception: There is an error in XML document. <ArrayOfAgency xmlns=''> was not expected
I've tried a million things with the XML, marking the class as Serializable, and it always returns this error. I looked at the code samples that the tutorial gives and I can't figure out why I'm getting this error.
VS for Windows, and maybe on Mac as well, has a special tool that will convert copied Xml into autogenerated classes. Now, it's not perfect but if you take your Xml file it generates a couple of classes similar to this:
public class ArrayOfAgency
{
public ArrayOfAgencyDbAgencyDefinition DbAgencyDefinition { get; set; }
}
public class ArrayOfAgencyDbAgencyDefinition
{
public string Name { get; set; }
public string Country { get; set; }
public string City { get; set; }
public string State { get; set; }
public string GtfsZipUrlDirectory { get; set; }
public string GtfsZipUrlFileName { get; set; }
}
As you might notice ArrayOfAgency is determined as a class holding a DbAgencyDefinition, which is why it's throwing an error while trying to deserialize it directly into a List<DbAgencyDefinition>. The type and what the serializer is expecting are not quite the same.
var serializer = new XmlSerializer(typeof(ArrayOfAgency));
var agencies = ((ArrayOfAgency)serializer.Deserialize(reader)).DbAgencyDefinition;
Also, as I mentioned the auto-generation may not be perfect because ArrayOfAgency may need to hold an array instead of a direct class if there can be more than one DbAgencyDefinition possible in Xml.
public class ArrayOfAgency
{
public ArrayOfAgencyDbAgencyDefinition[] DbAgencyDefinition { get; set; }
}
If you need more help or info on Xml Serialization check out the docs.
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication120
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
using (var reader = new StreamReader(FILENAME, Encoding.UTF8))
{
var serializer = new XmlSerializer(typeof(ArrayOfAgency));
ArrayOfAgency agencies = (ArrayOfAgency)serializer.Deserialize(reader);
}
}
}
public class ArrayOfAgency
{
public DbAgencyDefinition DbAgencyDefinition { get; set; }
}
public class DbAgencyDefinition
{
public string Name { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string GtfsZipUrlDirectory { get; set; }
public string GtfsZipUrlFileName { get; set; }
public string State { get; set; }
}
}
So I'm trying to retrieve the subscriber count from this xml file but I'm having an issue getting the data. Currently I'm using doc.DocumentElement.SelectSingleNode for each level but I'm not having much luck and as I'm not very familiar with C# xml I dont really know what my issue is. Any help would be much appreciated and the xml is attached below.
I am trying to get the data from the subscriberCount and my current code is attatched at the bottom, although it doesn't work
-Max
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<kind>youtube#channelListResponse</kind>
<etag>"xxx"</etag>
<pageInfo>
<totalResults>1</totalResults>
<resultsPerPage>1</resultsPerPage>
</pageInfo>
<items>
<kind>youtube#channel</kind>
<etag>"xxx"</etag>
<id>xxx</id>
<statistics>
<viewCount>0</viewCount>
<commentCount>0</commentCount>
<subscriberCount>200</subscriberCount>
<hiddenSubscriberCount>false</hiddenSubscriberCount>
<videoCount>5</videoCount>
</statistics>
</items>
</Root>
string totalSubs = doc.DocumentElement.SelectSingleNode("Root").SelectSingleNode("items").SelectSingleNode("statistics").SelectSingleNode("subscriberCount").Value;
Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement root = doc.Root;
Response response = new Response();
response.kind = (string)root.Element("kind");
response.etag = (string)root.Element("etag");
response.totalResults = (int)root.Descendants("totalResults").FirstOrDefault();
response.resultsPerPage = (int)root.Descendants("resultsPerPage").FirstOrDefault();
XElement items = root.Element("items");
response.itemKind = (string)items.Element("kind");
response.itemEtag = (string)items.Element("etag");
response.id = (string)items.Element("id");
XElement statistics = items.Element("statistics");
response.viewCount = (int)statistics.Element("viewCount");
response.commentCount = (int)statistics.Element("commentCount");
response.subscriberCount = (int)statistics.Element("subscriberCount");
response.hiddenSubscriberCount = (Boolean)statistics.Element("hiddenSubscriberCount");
response.videoCount = (int)statistics.Element("videoCount");
}
}
public class Response
{
public string kind { get; set; }
public string etag { get; set; }
public int totalResults { get; set; }
public int resultsPerPage { get; set; }
public string itemKind { get; set; }
public string itemEtag { get; set; }
public string id { get; set; }
public int viewCount { get; set; }
public int commentCount { get; set; }
public int subscriberCount { get; set; }
public Boolean hiddenSubscriberCount { get; set; }
public int videoCount { get; set; }
}
}
I'm doing a C# project and I have an object encoded in XML; an example instance would be:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Entity Type="StartRunTestSetResponse">
<Fields>
<Field Name="SuccessStaus">
<Value>2</Value>
</Field>
<Field Name="info">
<Value></Value>
</Field>
</Fields>
</Entity>
I need the attribute information because it is a necessity in the Key-Value pairs' the object has.
My deserialization grammar looks like this:
[DataContract(Name="Entity", Namespace="")]
[XmlSerializerFormat]
[KnownType(typeof(SRTSRField))]
[KnownType(typeof(SRTSRValue))]
public class StartRunTestSetResponse
{
[DataMember(Name="Type"), XmlAttribute("Type")]
public string type { get; set; }
[DataMember(Name = "Fields", IsRequired = true), XmlElement("Fields")]
public List<SRTSRField> fields { get; set; }
internal StartRunTestSetResponse() { fields = new List<SRTSRField>(); }
}
[DataContract(Name = "Field", Namespace = "")]
[KnownType(typeof(SRTSRValue))]
public class SRTSRField
{
[DataMember(Name = "Name"), XmlAttribute("Name")]
public string name {get; set;}
[DataMember(Name = "Value"), XmlElement("Value")]
public SRTSRValue value { get; set; }
}
[DataContract(Name = "Value", Namespace = "")]
public class SRTSRValue
{
[DataMember, XmlText]
public string value { get; set; }
}
Now, it doesn't work; at the moment it parses down to the Fields element and then any child of it is null.
You can simplify your model
public class Entity
{
[XmlAttribute]
public string Type { get; set; }
[XmlArrayItem("Field")]
public Field[] Fields { get; set; }
}
public class Field
{
[XmlAttribute]
public string Name { get; set; }
public string Value { get; set; }
}
So deserialization would be
XmlSerializer ser = new XmlSerializer(typeof(Entity));
using (StringReader sr = new StringReader(xmlstring))
{
var entity = (Entity)ser.Deserialize(sr);
}
[XmlRoot(ElementName="Field")]
public class Field {
[XmlElement(ElementName="Value")]
public string Value { get; set; }
[XmlAttribute(AttributeName="Name")]
public string Name { get; set; }
}
[XmlRoot(ElementName="Fields")]
public class Fields {
[XmlElement(ElementName="Field")]
public List<Field> Field { get; set; }
}
[XmlRoot(ElementName="Entity")]
public class Entity {
[XmlElement(ElementName="Fields")]
public Fields Fields { get; set; }
[XmlAttribute(AttributeName="Type")]
public string Type { get; set; }
}
Createdy by: http://xmltocsharp.azurewebsites.net/
It's really useful
I would create a dictionary using xml linq.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication74
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string,int?> dict1 = doc.Descendants("Field")
.GroupBy(x => (string)x.Attribute("Name"), y => string.IsNullOrEmpty((string)y.Element("Value")) ? null : (int?)y.Element("Value"))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}
I have an issue with my JSON to XML code. It's not assigning the values to the Object and I cannot figure out why. Please let me know what I am doing wrong.
My C# code:
using Newtonsoft.Json;
using System.Xml;
namespace JSONTest
{
public class Program
{
static void Main(string[] args)
{
string fileName = "C:\\Code\\JSONTest\\data\\response.xml";
// Convert XML Data into JSON Data
XmlDocument xmlFile = new XmlDocument();
xmlFile.Load(fileName);
string jsonData = JsonConvert.SerializeXmlNode(xmlFile);
// Convert JSON Data into Object
RootObject root = JsonConvert.DeserializeObject<RootObject>(jsonData);
var data = root.RESPONSE_GROUP;
Console.ReadLine();
}
}
public class RootObject
{
public RESPONSEGROUP RESPONSE_GROUP { get; set; }
}
public class RESPONSEGROUP
{
public string MISMOVersionID { get; set; }
public object RESPONDING_PARTY { get; set; }
public object RESPOND_TO_PARTY { get; set; }
public RESPONSE RESPONSE { get; set; }
}
public class RESPONSE
{
public string ResponseDateTime { get; set; }
public KEY KEY { get; set; }
public STATUS STATUS { get; set; }
}
public class KEY
{
public string _Name { get; set; }
public string _Value { get; set; }
}
public class STATUS
{
public string _Code { get; set; }
public string _Condition { get; set; }
public string _Description { get; set; }
public string _Name { get; set; }
}
}
XML
<RESPONSE_GROUP MISMOVersionID="2.4">
<RESPONDING_PARTY/>
<RESPOND_TO_PARTY/>
<RESPONSE ResponseDateTime="2015-02-19T10:32:11-06:00">
<KEY _Name="LOSClientID" _Value="3000799866"/>
<STATUS _Code="S0010" _Condition="Success" _Description="TEST DESC" _Name="Complete"/>
</RESPONSE>
</RESPONSE_GROUP>
My "JSONData" string:
{"RESPONSE_GROUP":{"#MISMOVersionID":"2.4","RESPONDING_PARTY":null,"RESPOND_TO_PARTY":null,"RESPONSE":{"#ResponseDateTime":"2015-02-19T10:32:11-06:00","KEY":{"#_Name":"LOSClientID","#_Value":"3000799866"},"STATUS":{"#_Code":"S0010","#_Condition":"Success","#_Description":"THIS IS THE DESCRIPTION.","#_Name":"Complete"}}}}
The value of: root.RESPONSE_GROUP.MISMOVersionID is NULL as well as any other values that should have been populated. I know I'm doing something wrong here, but I cannot figure out what it is.
Please help! Thanks in advance.
The problem is that your JSON contains # signs in front of some property names. For example:
"#MISMOVersionID":"2.4"
There are two options here:
Fix the JSON to not have that, e.g. "#MISMOVersionID":"2.4"
Use JsonPropertyAttribute to tell Json.NET which property name to expect in the JSON, e.g.
[JsonProperty("#MISMOVersionID")]
public string MISMOVersionID { get; set; }
i have another question on getting my XML serialization neat, which i can't seem to get right. my config file is as follows:
namespace SMCProcessMonitor
{
[Serializable()]
[XmlRoot("Email-Settings")]
public class Config
{
[XmlElement("Recipient")]
public string recipient;
[XmlElement("Server-port")]
public int serverport;
[XmlElement("Username")]
public string username;
[XmlElement("Password")]
public string password;
[XmlElement("Program")]
public List<Programs> mPrograms = new List<Programs>();
public string serialId;
}
public class Email
{
public string Recipient
{
get
{
return SMCProcessMonitor.ConfigManager.mConfigurations.recipient;
}
set
{
SMCProcessMonitor.ConfigManager.mConfigurations.recipient = value;
}
}
public int ServerPort
{
get
{
return SMCProcessMonitor.ConfigManager.mConfigurations.serverport;
}
set
{
SMCProcessMonitor.ConfigManager.mConfigurations.serverport = value;
}
}
public string Username
{
get
{
return SMCProcessMonitor.ConfigManager.mConfigurations.username;
}
set
{
SMCProcessMonitor.ConfigManager.mConfigurations.username = value;
}
}
public string Password { get; set; }
}
[Serializable()]
public class Programs
{
[XmlElement("Filename")] public string mFileName { get; set; }
[XmlElement("Filepath")]public string mFilePath { get; set; }
}
public class Database
{
public string mSerial { get; set; }
}
}
Ideally what i want to do is have each of these three classes (email settings, database and programs) have their own tags, like so
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<email-settings>
<Recipient>sadh</Recipient>
<Server-port>23</Server-port>
<Username>lkms</Username>
<Password>kmkdvm</Password>
</email-settings>
<Program>
<Filename>MerlinAlarm.exe</Filename>
<Filepath>D:\Merlin\Initsys\Merlin\Bin\MerlinAlarm.exe</Filepath>
</Program>
<database-settings>
<serialId>1</serialId>
</database-settings>
</Config>
But instead i get something that resembles this:
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Recipient>blah</Recipient>
<Server-port>1111</Server-port>
<Username>blah</Username>
<Password>blah</Password>
<Program>
<Filename>chrome.exe</Filename>
<Filepath>
C:\Users\Shane\AppData\Local\Google\Chrome\Application\chrome.exe
</Filepath>
</Program>
<serialId>1234</serialId>
</Config>
Sorry to be such a bother, but this is doing my nut in now and im sure there's some fundamental logic i'm missing here..can anyone give me some pointers as to how to get this XML in the format i specified above?
Thanks in advance, Shane.
Edit: My serialization class.
namespace SMCProcessMonitor
{
public class ShanesXMLserializer
{
private string mFileAndPath;
public Config mConfigurations = null;
public Config mConfigurationsProgram = null;
public ShanesXMLserializer(string inFileAndPath)
{
mFileAndPath = inFileAndPath;
mConfigurations = new Config();
}
public bool Write()
{
try
{
XmlSerializer x = new XmlSerializer(mConfigurations.GetType());
StreamWriter writer = new StreamWriter(mFileAndPath);
x.Serialize(writer, mConfigurations);
writer.Close();
return true;
}
catch (Exception ex)
{
MessageBox.Show("Exception found while writing: " + ex.Message);
};
return false;
}
public bool Read()
{
try
{
XmlSerializer x = new XmlSerializer(typeof(Config));
StreamReader reader = new StreamReader(mFileAndPath);
mConfigurations = (Config)x.Deserialize(reader);
reader.Close();
return true;
}
catch (Exception ex)
{
MessageBox.Show("Exception found while reading: " + ex.Message);
};
return false;
}
public Config GetConfigEmail
{
get
{
return mConfigurations;
}
}
}
}
Edit 2:
My new config file:
#Craig - I'm using this config file, which is like you said but im still not getting the desired XML, shown after my config class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.Text;
namespace SMCProcessMonitor
{
[Serializable()]
public class Config
{
public string recipient;
public int serverport;
public string username;
public string password;
public List<Programs> mPrograms = new List<Programs>();
public string serialId;
[XmlElement("email-settings")]
public Email Email { get; set; }
public Programs Programs { get; set; }
[XmlElement("database-settings")]
public Database Database { get; set; }
}
public class Email
{
[XmlElement("Recipient")]
public string Recipient { get; set; }
[XmlElement("Server-port")]
public int ServerPort { get; set; }
[XmlElement("Username")]
public string Username { get; set; }
[XmlElement("Password")]
public string Password { get; set; }
}
[Serializable()]
public class Programs
{
[XmlElement("Filename")] public string mFileName { get; set; }
[XmlElement("Filepath")]public string mFilePath { get; set; }
}
public class Database
{
[XmlElement("SerialID")]
public string mSerial { get; set; }
}
}
But i am still getting:
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<recipient>shane</recipient>
<serverport>23</serverport>
<username>oid</username>
<password>jidj</password>
<mPrograms/>
</Config>
This will give you the desired output:
public class Config
{
[XmlElement("email-settings")]
public Email Email { get; set; }
public Program Program { get; set; }
[XmlElement("database-settings")]
public Database Database { get; set; }
}
public class Email
{
public string Recipient { get; set; }
[XmlElement("Server-port")]
public int ServerPort { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
public class Program
{
public string Filename { get; set; }
public string Filepath { get; set; }
}
public class Database
{
public string serialId { get; set; }
}
Here's a console application which will serialize an object to a file and produce the exact XML you are looking for. Just copy and paste it into a console application and take it from there.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var config = new Config
{
Email = new Email
{
Recipient = "sadh",
ServerPort = 23,
Username = "lkms",
Password = "kmkdvm"
},
Program = new Programs
{
Filename = "MerlinAlarm.exe",
Filepath = #"D:\Merlin\Initsys\Merlin\Bin\MerlinAlarm.exe"
},
Database = new Database
{
serialId = "1"
}
};
XmlSerializer serializer = new XmlSerializer(typeof(Config));
var textWriter = new StreamWriter(#"C:\config.xml");
serializer.Serialize(textWriter, config);
textWriter.Close();
Console.Read();
}
}
#region [Classes]
public class Config
{
[XmlElement("email-settings")]
public Email Email { get; set; }
public Programs Program { get; set; }
[XmlElement("database-settings")]
public Database Database { get; set; }
}
public class Email
{
public string Recipient { get; set; }
[XmlElement("Server-port")]
public int ServerPort { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
public class Programs
{
public string Filename { get; set; }
public string Filepath { get; set; }
}
public class Database
{
public string serialId { get; set; }
}
#endregion
}
I'm going to suggest a totally sideways approach here, just for simplicity's and maintenance's sake.
What if you took the source XML file and generated an XSD schema?
For instance:
xsd.exe MyXMLFile1.xml
This will generate an XML schema file (MyXMLFile1.xsd). Take the schema and generate classes (again using xsd.exe):
xsd.exe /c MyXMLFile1.xsd
This will generate a guaranteed serializable POCO that you can use going forward. The class names and properties may not match what you have in your current POCO but it will generate the expected XML, as well as deserialize from the XML.
The added benefit is that going forward, you will only have to modify the source XML file, then run these 2 commands to maintain the POCO.
Hope that helps...