How to Deserialize XML using DataContractSerializer - c#

I'm trying to deserialize an xml document:
<?xml version="1.0"?>
<games xmlns = "http://serialize">
<game>
<name>TEST1</name>
<code>TESTGAME1</code>
<ugn>1111111</ugn>
<bets>
<bet>5,00</bet>
</bets>
</game>
<game>
<name>TEST2</name>
<code>TESTGAME2</code>
<ugn>222222</ugn>
<bets>
<bet>0,30</bet>
<bet>0,90</bet>
</bets>
</game>
</games>
.cs class:
namespace XmlParse
{
using System.Collections.Generic;
using System.Runtime.Serialization;
[DataContract(Namespace = "http://serialize")]
public class game
{
#region Public Properties
[DataMember]
public string name { get; set; }
[DataMember]
public string code { get; set; }
[DataMember]
public long ugn { get; set; }
[DataMember]
public List<decimal> bets { get; set; }
#endregion
}
[KnownType(typeof(game))]
[DataContract(Namespace = "http://serialize")]
public class games
{
#region Public Properties
[DataMember]
public List<game> game { get; set; }
#endregion
}
}
Main:
FileStream fs = new FileStream(Path.Combine(this.path, xmlDocumentName), FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(games));
// Deserialize the data and read it from the instance.
games deserializedPerson = (games)ser.ReadObject(reader, true);
reader.Close();
fs.Close();
deserializedPerson shows count = 0
what gives?

I figured it out. Maybe there are other implementations but this works. For the life of me I couldn't find any examples that use List inside an object. Here is a working example:
XML document to parse:
<?xml version="1.0"?>
<games xmlns = "http://serialize">
<game>
<name>TEST1</name>
<code>TESTGAME1</code>
<ugn>1111111</ugn>
<bets>
<bet>5,00</bet>
</bets>
</game>
<game>
<name>TEST2</name>
<code>TESTGAME2</code>
<ugn>222222</ugn>
<bets>
<bet>0,30</bet>
<bet>0,90</bet>
</bets>
</game>
</games>
.cs class:
namespace XmlParse
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization;
[DataContract(Name = "game", Namespace = "")]
public class Game
{
[DataMember(Name = "name", Order = 0)]
public string Name { get; private set; }
[DataMember(Name = "code", Order = 1)]
public string Code { get; private set; }
[DataMember(Name = "ugn", Order = 2)]
public string Ugn { get; private set; }
[DataMember(Name = "bets", Order = 3)]
public Bets Bets { get; private set; }
}
[CollectionDataContract(Name = "bets", ItemName = "bet", Namespace = "")]
public class Bets : List<string>
{
public List<decimal> BetList
{
get
{
return ConvertAll(y => decimal.Parse(y, NumberStyles.Currency));
}
}
}
[CollectionDataContract(Name = "games", Namespace = "")]
public class Games : List<Game>
{
}
}
Read and parse xml document:
string fileName = Path.Combine(this.path, "Document.xml");
DataContractSerializer dcs = new DataContractSerializer(typeof(Games));
FileStream fs = new FileStream(fileName, FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
Games games = (Games)dcs.ReadObject(reader);
reader.Close();
fs.Close();

Related

Serialize object directly to CData

I need to make a api where in the request body there needs to be a CData object. All works exept that I cant figure out how to make my object serialze into a CData object. The project is written in the .net-framework.
I currently have the following code.
C#:
[XmlRoot(ElementName = "DATA")]
public class DATA
{
[XmlElement(ElementName = "ID")]
public int ID { get; set; }
[XmlElement(ElementName = "NAME")]
public string NAME{ get; set; }
}
[XmlRoot(ElementName = "NewDataSet")]
public class CDataSet
{
[XmlElement(ElementName = "DATA")]
public DATA data{ get; set; }
}
How the xml needs to look after:
<![CDATA[
<NewDataSet>
<DATA>
<ID>007</ID>
<NAME>John</NAME>
</DATA>
</NewDataSet>
]]>
I can make it working by serializing normally by making a request to this function:
public static string SerializeObject<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
Than manual adding the CData parts around it.
However my boss wants it make it work without manually adding the parts.
Please note I'm very new to C#.
Any step in the right direction will help. Thanks!
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 ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
CDataSet data = new CDataSet()
{
data = new DATA() { ID = "007", NAME = "John" }
};
MemoryStream stream = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(stream, settings);
XmlSerializer serializer = new XmlSerializer(typeof(CDataSet));
serializer.Serialize(writer, data);
writer.Flush();
writer.Close();
stream.Position = 0;
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
string xml = Encoding.UTF8.GetString(buffer);
string output = string.Format("<![CDATA[\n{0}\n]]>", xml);
}
}
[XmlRoot(ElementName = "DATA", Namespace = "")]
public class DATA
{
private int _ID { get; set; }
[XmlElement(ElementName = "ID")]
public string ID {
get { return _ID.ToString("D3");}
set{ _ID = int.Parse(value);}
}
[XmlElement(ElementName = "NAME")]
public string NAME { get; set; }
}
[XmlRoot(ElementName = "NewDataSet")]
public class CDataSet
{
[XmlElement(ElementName = "DATA")]
public DATA data { get; set; }
}
}

How to process the XML file having hierarchical structure to get the inner details

I have a large xml file with following structure.This is a snippet which contains many <xn:TestElement> nodes.
<?xml version="1.0" encoding="utf-8" ?>
<testDataFile
xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData"
xmlns:xn="http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm" xmlns:in="http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm">
<fileHeader fileFormatVersion="32.615 V6.3" vendorName="TestVendor"/>
<configData dnPrefix="">
<xn:SubNetwork id="ONRM_ROOT_MO">
<xn:SubNetwork id="RNC425">
<xn:TestElement id="DA_Test_place0">
<xn:attributes>
<xn:userLabel>DA_Test_place0</xn:userLabel>
</xn:attributes>
<in:InventoryUnit id="n/a">
<in:attributes>
<in:manufacturerData>ProductName=Non-subrack HW,SlotCount=0</in:manufacturerData>
</in:attributes>
<in:InventoryUnit id="0">
<in:attributes>
<in:vendorUnitTypeNumber>KRC11876/1_R4A</in:vendorUnitTypeNumber>
<in:manufacturerData>ProductName=RUS 02 B8</in:manufacturerData>
</in:attributes>
</in:InventoryUnit>
<in:InventoryUnit id="0">
<in:attributes>
<in:vendorUnitTypeNumber>test/1_R4A</in:vendorUnitTypeNumber>
</in:attributes>
</in:InventoryUnit>
</in:InventoryUnit>
<in:InventoryUnit id="n/a">
<in:attributes>
<in:manufacturerData>ProductName=Virtual subrack,SlotCount=2</in:manufacturerData>
</in:attributes>
<in:InventoryUnit id="1">
<in:attributes>
<in:vendorUnitTypeNumber>KDU127174/4_R2D/A</in:vendorUnitTypeNumber>
</in:attributes>
</in:InventoryUnit>
<in:InventoryUnit id="1">
<in:attributes>
<in:vendorUnitTypeNumber>KDU127174/4_R2D/B</in:vendorUnitTypeNumber>
<in:manufacturerData>ProductName=RUS 02 B7</in:manufacturerData>
</in:attributes>
</in:InventoryUnit>
</in:InventoryUnit>
</xn:TestElement>
<xn:TestElement id="DA_Test_place1">
</xn:TestElement>
</xn:SubNetwork>
</xn:SubNetwork>
</configData>
</testDataFile>
Now I want to process this xml get information like:
testelementname slotdata inventory unit number
------------------------------------------------------------------------------
DA_Test_place0 ProductName=Non-subrack HW,SlotCount=0 KRC11876/1_R4A
DA_Test_place0 ProductName=Non-subrack HW,SlotCount=0 test/1_R4A
DA_Test_place0 ProductName=Virtual subrack,SlotCount=2 KDU127174/4_R2D/A
DA_Test_place0 ProductName=Virtual subrack,SlotCount=2 KDU127174/4_R2D/B
How can I process this xml file and get information either in datatable or C# classes. I wrote the following code, but it got stuck with the hierarchy of xml
while (reader.Read())
{
if (reader.Name != "xn:TestElement")
{
reader.ReadToFollowing("xn:TestElement");
}
while (reader.NodeType == XmlNodeType.Element && reader.LocalName == "TestElement")
{
XElement elements = (XElement)XElement.ReadFrom(reader);
testelemenname = reader.GetAttribute("id");
slotdata = GetInventoryValue(elements, "manufacturerData");
invenotry unit number = GetInventoryValue(elements, "vendorUnitTypeNumber");
}
}
private static string GetInventoryValue(XElement pin, string input)
{
XElement manufacturerData = pin.Descendants().Where(a => a.Name.LocalName == input).FirstOrDefault();
if (manufacturerData != null)
{
return (string)manufacturerData;
}
}
EDIT
Heirarchy of XML changed a bit and added two level 'SubNetwork' node and one more node 'configData'and namespaces also changed,now i am not getting the result
You can achieve your desired result by using XDocument.
Here I created a sample console app for your demonstration purpose,
class Program
{
public static void Main(string[] args)
{
XDocument doc = XDocument.Load(#"Path to your xml file");
XNamespace ns = doc.Root.GetDefaultNamespace();
XNamespace xdt = "http://www.3gpp.org";
var result = doc.Descendants(ns + "TestElement")
.Elements(ns + "InventoryUnit")
.Elements(ns + "InventoryUnit")
.Select(x => new
{
test_element_name = x.AncestorsAndSelf(ns + "TestElement").FirstOrDefault()?.Attribute("id")?.Value,
slot_data = x.Ancestors(ns + "InventoryUnit").AncestorsAndSelf(ns + "InventoryUnit").FirstOrDefault().Element(ns + "attributes").Element(ns + "manufacturerData")?.Value,
invenotry_unit_number = x.Element(ns + "attributes").Element(ns + "vendorUnitTypeNumber")?.Value,
}).ToList();
//-----------Print result--------------
foreach (var item in result)
{
Console.WriteLine(item.test_element_name);
Console.WriteLine(item.slot_data);
Console.WriteLine(item.invenotry_unit_number);
Console.WriteLine();
}
Console.ReadLine();
}
}
Output:
Edit:
If your xml file size is too large and XDocument failed to parse it then you can try XmlSerializer like
XmlSerializer serializer = new XmlSerializer(new TestDataFile().GetType());
using (StringReader stringReader = new StringReader(File.ReadAllText(#"Path to your xml file")))
{
TestDataFile testDataFile = (TestDataFile)serializer.Deserialize(stringReader);
var result = testDataFile.ConfigData.SubNetwork.InnerSubNetwork.SelectMany(a => a.TestElement.SelectMany(x => x.InventoryUnit.SelectMany(y => y.IU
.Select(z => new { test_element_name = x.Id, slot_data = y.Attributes.ManufacturerData, invenotry_unit_number = z.Attributes.VendorUnitTypeNumber })))).ToList();
foreach (var item in result)
{
Console.WriteLine(item.test_element_name);
Console.WriteLine(item.slot_data);
Console.WriteLine(item.invenotry_unit_number);
Console.WriteLine();
}
}
And you need below class hierarchy to deserialize your xml,
[XmlRoot(ElementName = "fileHeader", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class FileHeader
{
[XmlAttribute(AttributeName = "fileFormatVersion")]
public string FileFormatVersion { get; set; }
[XmlAttribute(AttributeName = "vendorName")]
public string VendorName { get; set; }
}
[XmlRoot(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class Attributes
{
[XmlElement(ElementName = "userLabel", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string UserLabel { get; set; }
[XmlElement(ElementName = "manufacturerData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string ManufacturerData { get; set; }
[XmlElement(ElementName = "vendorUnitTypeNumber", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string VendorUnitTypeNumber { get; set; }
}
[XmlRoot(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class InnerInventoryUnit
{
[XmlElement(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public Attributes Attributes { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class InventoryUnit
{
[XmlElement(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public Attributes Attributes { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public List<InnerInventoryUnit> IU { get; set; }
}
[XmlRoot(ElementName = "TestElement", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class TestElement
{
[XmlElement(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public List<InventoryUnit> InventoryUnit { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class InnerSubNetwork
{
[XmlElement(ElementName = "TestElement", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public List<TestElement> TestElement { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class SubNetwork
{
[XmlElement(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public List<InnerSubNetwork> InnerSubNetwork { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "configData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public class ConfigData
{
[XmlElement(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public SubNetwork SubNetwork { get; set; }
[XmlAttribute(AttributeName = "dnPrefix")]
public string DnPrefix { get; set; }
}
[XmlRoot(ElementName = "testDataFile", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public class TestDataFile
{
[XmlElement(ElementName = "fileHeader", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public FileHeader FileHeader { get; set; }
[XmlElement(ElementName = "configData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public ConfigData ConfigData { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName = "xn", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xn { get; set; }
[XmlAttribute(AttributeName = "in", Namespace = "http://www.w3.org/2000/xmlns/")]
public string In { get; set; }
}

XML Deserialization Coming up NULL

My Deserializer executes without exception, but the resulting object is coming up with nulls. The source XML clearly shows values that for some reason are not being set in the target object. I can't for the life of me figure out why?
Source XML:
<soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>soapenv:Client</faultcode>
<faultstring>Could not insert new row - duplicate value in a UNIQUE INDEX column (Unique Index:).</faultstring>
<detail>
<axlError>
<axlcode>-239</axlcode>
<axlmessage>Could not insert new row - duplicate value in a UNIQUE INDEX column (Unique Index:).</axlmessage>
<request>addRoutePartition</request>
</axlError>
</detail>
Class:
using System.Xml.Serialization;
namespace AXLClassLibrary
{
[XmlRoot(ElementName = "Fault", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Fault
{
[XmlElement(ElementName = "faultcode")]
public string Faultcode { get; set; }
[XmlElement(ElementName = "faultstring")]
public string Faultstring { get; set; }
[XmlElement(ElementName = "detail")]
public Detail Detail { get; set; }
[XmlAttribute(AttributeName = "soapenv", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Soapenv { get; set; }
}
[XmlRoot(ElementName = "axlError")]
public class AxlError
{
[XmlElement(ElementName = "axlcode")]
public string Axlcode { get; set; }
[XmlElement(ElementName = "axlmessage")]
public string Axlmessage { get; set; }
[XmlElement(ElementName = "request")]
public string Request { get; set; }
}
[XmlRoot(ElementName = "detail")]
public class Detail
{
[XmlElement(ElementName = "axlError")]
public AxlError AxlError { get; set; }
}
}
Deserializer Code:
var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
XDocument xd = XDocument.Parse(resp);
XNamespace ns1 = "http://schemas.xmlsoap.org/soap/envelope/";
XNode faultXML = xd.Descendants(ns1 + "Fault").DescendantNodesAndSelf().First();
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "Fault";
xRoot.Namespace = "http://schemas.xmlsoap.org/soap/envelope/";
xRoot.IsNullable = false;
resp = faultXML.ToString();
Fault currentFault;
XmlSerializer serializer = new XmlSerializer(typeof(Fault), xRoot);
using (TextReader readFault = new StringReader(resp))
{
currentFault = (Fault)serializer.Deserialize(readFault);
}

xml serialization in ASP.NET WEB API

Im developing a web api in C#. The web api should return an xml like:
<personDatas>
<personData>
<affdatalist>
<object1> information </object1>
<object2> information </object2>
<object3> information </object3>
</affdatalist>
<anotherObject1> infooo </anotherObject1>
<anotherObject2> infooo </anotherObject2>
</personData>
</personDatas>
The xml can have 1 to many personData elements and the personData element can have 1 to many affdatalist elements.
What would be the best practice to generate such an XML in a web api using C# 6?
Ive tried with XSD based on a schema definition.
Any help would be greatly appreciated.
You can use the Serialize method to generate this xml from the model it self.
public string SerializeXml<T>(T config)
{
XmlSerializer xsSubmit = new XmlSerializer(typeof(T));
string xml = "";
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = false;
using (var sww = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww, settings))
{
xsSubmit.Serialize(writer, config);
xml = sww.ToString();
}
}
return xml;
}
This will return XML string , you need the model which is similar to your required XML.
This is what i have created as model from your XML that you can change as per your requiment.
[XmlRoot(ElementName = "affdatalist")]
public class Affdatalist
{
[XmlElement(ElementName = "object1")]
public string Object1 { get; set; }
[XmlElement(ElementName = "object2")]
public string Object2 { get; set; }
[XmlElement(ElementName = "object3")]
public string Object3 { get; set; }
}
[XmlRoot(ElementName = "personData")]
public class PersonData
{
[XmlElement(ElementName = "affdatalist")]
public Affdatalist Affdatalist { get; set; }
[XmlElement(ElementName = "anotherObject1")]
public string AnotherObject1 { get; set; }
[XmlElement(ElementName = "anotherObject2")]
public string AnotherObject2 { get; set; }
}
[XmlRoot(ElementName = "personDatas")]
public class PersonDatas
{
[XmlElement(ElementName = "personData")]
public PersonData PersonData { get; set; }
}
You can use as sample below
PersonDatas data = new PersonDatas();
var xml = this.SerializeXml<PersonDatas>(data); // your model with data
This is my sample after using what Sulay Shah said:
PersonDatas data = new PersonDatas();
for (int x = 0; x < 2; x++)
{
data.PersonData = new PersonData();
for (int i = 0; i < 2; i++)
{
Affdatalist affdata = new Affdatalist();
affdata.Object1 = "LALALALALLALA";
affdata.Object2 = "lqlqlqlqlqlqlql";
affdata.Object3 = "ililililililililililil";
data.PersonData.Affdatalist.Add(affdata);
}
data.PersonData.AnotherObject1 = "ali";
data.PersonData.AnotherObject2 = "Nazar";
data.personDataList.Add(data.PersonData);
}
var xml = this.SerializeXml<PersonDatas>(data);
return xml;
The above generated below
xml:<?xml version="1.0" encoding="utf-16"?>
<personDatas xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<personData>
<affdatalist>
<object1>LALALALALLALA</object1>
<object2>lqlqlqlqlqlqlql</object2>
<object3>ililililililililililil</object3>
</affdatalist>
<affdatalist>
<object1>LALALALALLALA</object1>
<object2>lqlqlqlqlqlqlql</object2>
<object3>ililililililililililil</object3>
</affdatalist>
<anotherObject1>ali</anotherObject1>
<anotherObject2>Nazar</anotherObject2>
</personData>
<personData>
<affdatalist>
<object1>LALALALALLALA</object1>
<object2>lqlqlqlqlqlqlql</object2>
<object3>ililililililililililil</object3>
</affdatalist>
<affdatalist>
<object1>LALALALALLALA</object1>
<object2>lqlqlqlqlqlqlql</object2>
<object3>ililililililililililil</object3>
</affdatalist>
<anotherObject1>ali</anotherObject1>
<anotherObject2>Nazar</anotherObject2>
</personData>
<PersonData>
<affdatalist>
<object1>LALALALALLALA</object1>
<object2>lqlqlqlqlqlqlql</object2>
<object3>ililililililililililil</object3>
</affdatalist>
<affdatalist>
<object1>LALALALALLALA</object1>
<object2>lqlqlqlqlqlqlql</object2>
<object3>ililililililililililil</object3>
</affdatalist>
<anotherObject1>ali</anotherObject1>
<anotherObject2>Nazar</anotherObject2>
</PersonData>
</personDatas>
If you want c# classes like this
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace namespace
{
public class AffData {
public string Property1 { get; set; }
}
public class AnotherObject1 {
public string Property1 { get; set; }
}
public class AnotherObject2 {
public string Property1 { get; set; }
}
public class PersonData {
public List<AffData> AffDataList { get; set; }
public AnotherObject1 AnotherObject1 { get; set; }
public AnotherObject2 AnotherObject2 { get; set; }
}
The below xml will work if you serialize List
<ArrayOfPersonData>
<PersonData>
<ArrayOfAffData>
<AffData>
<Property1>info</Property1>
</AffData>
<AffData> <Property1>info</Property1></AffData>
<AffData> <Property1>info</Property1> </AffData>
</ArrayOfAffData>
<anotherObject1> <Property1>info</Property1> </anotherObject1>
<anotherObject2> <Property1>info</Property1> </anotherObject2>
</PersonData>
</ArrayOfPersonData>
public static string ConvertToXml(object payload, string rootElement, bool addPrefixSuffix)
{
string json = JsonConvert.SerializeObject(payload);
string elementName = "DummyRoot";
if (addPrefixSuffix)
{
string prefix = "{" + elementName + ":";
string postfix = "}";
json = string.Concat(prefix, json, postfix);
}
var payloadXml = JsonConvert.DeserializeXNode(json, rootElement)?.ToString();
if (addPrefixSuffix)
{
payloadXml = payloadXml.ToString().Replace("<" + elementName + ">", string.Empty);
payloadXml = payloadXml.ToString().Replace("</" + elementName + ">", string.Empty);
}
return Regex.Replace(payloadXml, #"\s+", String.Empty);
}
Use the above function like ConvertToXml(requeststring, "", false)... Here second parameter empty will returns your expected result.

C# Xml Serialize Attribute Adding Custom Namespace

I am trying to add namespace during Xml Serialization. So far I have added some of them but I am unable to add custom namespace using Xml serializer.
So far I have achieved this
<?xml version="1.0"?>
<manifest xmlns:xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2e" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2" xsi:schemaLocation="http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xs" identifier="test" version="2">
<lom xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test lom" xmlns="http://ltsc.ieee.org/xsd/LOM" />
<resource adlcp:scormtype="sco" />
</manifest>
This is my Code
Manifest Class
[Serializable]
[XmlRoot(ElementName = "manifest")]
public class Manifest
{
/// <summary>
/// manifest root node
/// </summary>
[XmlAttribute(AttributeName = "identifier")]
public string Identifier { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
//[XmlAttribute(AttributeName = "adlcp", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
//public string Adlcp = "http://www.adlnet.org/xsd/adlcp_rootv1p2";
[XmlAttribute(AttributeName = "schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string SchemaLocation = "http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xs";
[XmlElement(ElementName = "lom", Namespace = "http://ltsc.ieee.org/xsd/LOM")]
public Lom Lom { get; set; }
[XmlElement("resource")]
public Resource Resource { get; set; }
}
Lom Class
public class Lom
{
[XmlAttribute(AttributeName = "schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string SchemaLocation { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.imsproject.org/xsd/imscp_rootv1p1p2e")]
public string Xsi = "http://www.w3.org/2001/XMLSchema-instance";
}
Resource Class
public class Resource
{
[XmlAttribute(AttributeName = "scormtype", Namespace = "http://www.adlnet.org/xsd/adlcp_rootv1p2")]
public string ScormType { get; set; }
}
My serialization function like this
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
var xmlSerializer = new XmlSerializer(typeof(Manifest));
var ns = new XmlSerializerNamespaces();
ns.Add("xmlns", "http://www.imsproject.org/xsd/imscp_rootv1p1p2e");
ns.Add("adlcp", "http://www.adlnet.org/xsd/adlcp_rootv1p2");
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xmlSerializer.Serialize(fs, data, ns);
fs.Close();
}
I need output like this.
<?xml version="1.0"?>
<manifest
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
identifier="test" version="2"
xmlns:adlcp="test"
xsi:schemaLocation="test location"
**xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"**>
<lom
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ltsc.ieee.org/xsd/LOM lom.xsd"
xmlns="http://ltsc.ieee.org/xsd/LOM" />
<resource adlcp:scormtype="sco"/>
</manifest>
what I am doing wrong?
Simply add a namspace serializer
var xmlSerializer = new XmlSerializer(typeof(Manifest), "http://www.w3.org/2001/XMLSchema-instance");
var ns = new XmlSerializerNamespaces();
ns.Add("xmlns", "http://www.w3.org/2001/XMLSchema-instance");
xmlSerializer.Serialize(fs, data, ns);
and if data is defined as
Manifest data = new Manifest()
{ Identifier = "test", Version = "2", Adlcp = "test", SchemaLocation = "test location" };
data.Resource = new Resource() { ScormType="sco" };
with an attribute
[XmlAttribute(AttributeName = "adlcp", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Adlcp { get; set; }
you'll get xmlns:adlcp="test" in the output
Same thing for
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Xsi = "http://www.w3.org/2001/XMLSchema-instance";
As well as
ns.Add("adlcp", "http://www.imsproject.org/xsd/Manifest/Adlcp");
with
[XmlAttribute(AttributeName = "scormtype", Namespace = "http://www.imsproject.org/xsd/Manifest/Adlcp")]
public string ScormType { get; set; }
to get a possible adlcp:scormtype="sco"
Add a namespace to the root class too, for example
[XmlRoot(ElementName = "manifest", Namespace = "http://www.imsproject.org/xsd/Manifest")]
public class Manifest

Categories

Resources