.Net Xml serialization appending negative sign to 0 - c#

I am trying to serialize the object which is having properties of type double value but output xml is having the one of the parameter value as "-0".
I am using .Net framework 3.5.
Sample code:
[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
Public class Data
{
[XmlElement(Form = XmlSchemaForm.Unqualified)]
public double Lateral { get; set;}
}
public class Test
{
Public static void Main()
{
Test t=new Test();
Data data=new Data();
data.Lateral=0;
string xml = t.ToXml(data);
Console.WriteLine(xml);
}
Public string ToXml(Data data)
{
using (StringWriter stringWriter = new StringWriter())
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Data));
xmlSerializer.Serialize(stringWriter, data);
return stringWriter.ToString();
}
}
}
}
Output xml:
<?xml version="1.0" encoding="utf-16"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lateral>-0</Lateral>
</Data>

Sometimes it happens with double 0. you can try a very simple trick
public class Data
{
private double _lateral;
public double Lateral
{
get { return _lateral + 0 ; }
set { _lateral = value; }
}
//or
public double Lateral
{
get { return _lateral; }
set { _lateral = value + 0 ; }
}
}

Related

Unable to Deserialize XML in C# - Unrecgnized element 'add'

I have a C# app that uses a custom section for configuration. I have that section of XML defined as a string. The string looks like this:
var xml = #"<departments>
<department id=""1"" name=""Sporting Goods"">
<products>
<product name=""Basketball"" price=""9.99"">
<add key=""Color"" value=""Orange"" />
<add key=""Brand"" value=""[BrandName]"" />
</product>
</products>
</department>
</departments>";
This XML matches the schema defined by the classes I described here. When I pass the above string to the Departments.Deserialize method, I receive an error. The error says: "Unrecognized element 'add'". The debugger jumps to this line in my Departments class.
public void ReadXml(XmlReader reader)
{
this.DeserializeElement(reader, false);
}
I assume that the error is referring to the 'add' elements in the 'product' element. However, the Product ConfigurationElement has a property named KeyValueConfigurationCollection Items. For that reason, it seems that add would work.
Why am I getting this error how do I fix my code so that the XML string shown above can be deserialized?
Update: Long story short - wrong serializer.
Most of the code works, except that particular deserialize method.
I was able to rectify original solution (here's where I found inspiration).
The section that I've corrected and it worked (don't forget IXmlSerializable from original post):
private static string sectionName = "departments";
public static Departments Deserialize(string xml)
{
XmlSerializer serializer = new XmlSerializer(typeof(Departments), new XmlRootAttribute(sectionName));
Departments departments = null;
var xdoc = XDocument.Parse(xml);
departments = (Departments)serializer.Deserialize(xdoc.CreateReader());
//var serializer = new XmlSerializer(typeof(Departments));
//using (var reader = new StringReader(xml))
//{
// departments = (Departments)(serializer.Deserialize(reader));
//}
return departments;
}
Hopefully it will help you moving on. At least works on my machine. Let me know if full code listing needed.
[Keeping original solution, plain reading of suggested problematic xml block]
Test client.
class Program
{
static void Main(string[] args)
{
string str = #"<departments>
<department id = ""1"" name = ""Sporting Goods"">
<products>
<product name=""Basketball"" price=""9.99"">
<add key = ""Color"" value = ""Orange""/>
<add key = ""Brand"" value = ""[BrandName]""/>
</product>
</products>
</department>
</departments>";
XmlDocument xmlDoc = LoadXmlsFromString(str);
string productXpath = "descendant-or-self::product";
var nodes = ExtractNodes(xmlDoc, productXpath);
foreach (XmlNode childrenNode in nodes)
{
var node = childrenNode.SelectSingleNode("descendant-or-self::*")?.OuterXml;
var obj = Product.Deserialize(node);
}
}
private static XmlNodeList ExtractNodes(XmlDocument xmlDoc, string xpath)
{
var nodes = xmlDoc.SelectNodes(xpath);
return nodes;
}
private static XmlDocument LoadXmlsFromString(string str)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(str);
return xmlDoc;
}
}
Reading product is implemented by adding [XmlElement("add")] attribute for the list of add elements (and element-object to convert into).
[Serializable, XmlRoot("add")]
public class KeyValue
{
[XmlAttribute(AttributeName = "key")]
public string Key { get; set; }
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
public static KeyValue Deserialize(string xml)
{
KeyValue keyValue = null;
var serializer = new XmlSerializer(typeof(KeyValue));
using (var reader = new StringReader(xml))
{
keyValue = (KeyValue)(serializer.Deserialize(reader));
}
return keyValue;
}
}
[Serializable, XmlRoot("product")]
public class Product
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlAttribute(AttributeName = "price")]
public decimal Price { get; set; }
[XmlElement("add")]
public List<KeyValue> KeyValueList { get; set; }
public static Product Deserialize(string xml)
{
Product product = null;
var serializer = new XmlSerializer(typeof(Product));
using (var reader = new StringReader(xml))
{
product = (Product)(serializer.Deserialize(reader));
}
return product;
}
}
In my opinion an XmlSerializer is not needed for the configurations you have to read. All the tools that System.Configuration provides you are more than enough. Here I rewrote your configuration classes (the basic structure):
public class DepartmentsConfiguration : ConfigurationSection
{
[ConfigurationProperty("departments", IsRequired = false, IsDefaultCollection = true)]
public DepartmentItemCollection Departments
{
get
{
var departments = this["departments"] as DepartmentItemCollection;
return departments;
}
set
{
this["departments"] = value;
}
}
}
[ConfigurationCollection(typeof(DepartmentItemCollection), AddItemName = "department")]
public class DepartmentItemCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new Department();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Department)element).Name;
}
}
public class Department : ConfigurationElement
{
[ConfigurationProperty("id", IsRequired = false, IsKey = true)]
public int Id
{
get
{
return (int)(this["id"]);
}
set
{
this["id"] = value;
}
}
[ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
public string Name
{
get
{
return (string)(this["name"]);
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("products", IsRequired = false, IsKey = false, IsDefaultCollection = false)]
public ProductCollection Products
{
get
{
return (ProductCollection)this["products"];
}
set
{
this["products"] = value;
}
}
}
[ConfigurationCollection(typeof(ProductCollection), AddItemName = "product")]
public class ProductCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new Product();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Product)element).Name;
}
}
public class Product : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
public string Name
{
get
{
return (string)(this["name"]);
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("price", IsRequired = false)]
public decimal Price
{
get
{
return (decimal)(this["price"]);
}
set
{
this["price"] = value;
}
}
[ConfigurationProperty("", IsRequired = false, IsKey = false, IsDefaultCollection = true)]
[ConfigurationCollection(typeof(KeyValueConfigurationCollection), AddItemName = "add")]
public KeyValueConfigurationCollection Items
{
get
{
var items = base[""] as KeyValueConfigurationCollection;
return items;
}
set
{
base[""] = value;
}
}
}
The <configSections> in App.config:
<configSections>
<section
name="departmentConfiguration"
type="Test.DepartmentsConfiguration, Test"
allowLocation="true"
allowDefinition="Everywhere"
/>
</configSections>
<departmentConfiguration>
<departments>
<department id="1" name="Sporting Goods">
<products>
<product name="Basketball" price="9.99">
<add key="Color" value="Orange" />
<add key="Brand" value="[BrandName]" />
</product>
</products>
</department>
</departments>
</departmentConfiguration>
And how to read it using the ConfigurationManager:
DepartmentsConfiguration config = (DepartmentsConfiguration) ConfigurationManager
.GetSection("departmentConfiguration");
foreach (Department department in config.Departments)
{
Console.WriteLine($"{department.Id}, {department.Name}");
foreach (Product product in department.Products)
{
Console.WriteLine($"{product.Name}, {product.Price}");
foreach (string key in product.Items.AllKeys)
{
Console.WriteLine($"{key} -> {product.Items[key].Value}");
}
}
}
I know it is not consistent with your question, take it as a personal advice.
How about using System.Xml.Linq's XDocument ?
Personal Pros:
Simple
No 3rd Party
Easy to read, for smaller files
Allows Linq Syntax
Personal Cons:
Tends towards spaghetti code in bigger files
Not the fastest solution
Example
static void Main(string[] args)
{
var xml =
#"<departments>
<department id=""1"" name=""Sporting Goods"">
<products>
<product name=""Basketball"" price=""9.99"">
<add key=""Color"" value=""Orange"" />
<add key=""Brand"" value=""[BrandName]"" />
</product>
</products>
</department>
</departments>";
var xDoc = XDocument.Load(new StringReader(xml));
var adds = xDoc.Root.Elements("department")
.Elements("products")
.Elements("product")
.Elements("add")
.Select(s => new KeyValuePair<string, string>(s.Attribute("key").ToString(), s.Attribute("value").ToString()))
.ToList();
foreach (var department in xDoc.Root.Elements("department"))
{
Console.WriteLine("department: {0}", department.Attribute("name"));
foreach (var products in department.Elements("products"))
{
foreach (var product in products.Elements("product"))
{
Console.WriteLine("product: {0}", product.Attribute("name"));
foreach (var config in product.Elements("add"))
{
Console.WriteLine("add: {0} -> {1}", config.Attribute("key"), config.Attribute("value"));
}
}
}
}

How to create xml with attribute using XmlSerializer?

I'm working on xml generation using list to direct xml of generic class, but getting wrong result of xml.
I want below output from XmlSerializer.
<root>
<rating city="A" code="A1">A++</rating>
<rating city="B" code="A2">A</rating>
<rating city="C" code="A3">AB</rating>
</root>
currently i'm getting this
<ratings reason="reason123">
<rating>R</rating>
</ratings>
<ratings reason="reason123">
<rating>R</rating></ratings>
C# Code
public class root
{
[XmlAttribute("city")]
public string city { get; set; }
[XmlAttribute("code")]
public string code { get; set; }
[XmlElement("rating")]
public string rating { get; set; }
}
string tempXML6 = XmlExtensions.Serialize(rootList)
static public void Serialize(object classobject)
{
XmlSerializer SerializedObject = new XmlSerializer(classobject.GetType());
using (MemoryStream xmlStream = new MemoryStream())
{
SerializedObject.Serialize(xmlStream, classobject);
xmlStream.Position = 0;
//Loads the XML document from the specified string.
XmlDocument resultDocument = new XmlDocument();
resultDocument.Load(xmlStream);
if (!string.IsNullOrEmpty(resultDocument.DocumentElement.InnerXml))
{
return resultDocument.DocumentElement.InnerXml;
}
else
{
return string.Empty;
}
}
}
please let me know what's needs to be change.
Your object model is wrong. It should be something like this.
[XmlRoot("root")]
public class Root
{
[XmlElement("rating")]
public Rating[] Ratings { get; set; }
}
public class Rating
{
[XmlAttribute("city")]
public string City { get; set; }
[XmlAttribute("code")]
public string Code { get; set; }
[XmlText]
public string Value { get; set; }
}
To serialize the object do this
Root root = new Root
{
Ratings = new Rating[]
{
new Rating { City = "A", Code = "A1", Value = "A++" },
new Rating { City = "B", Code = "A2", Value = "A" },
new Rating { City = "C", Code = "A3", Value = "AB" }
}
};
string serializedObject = Serialize(root);
This is the serialize method
public static string Serialize<T>(T item)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringWriter stringWriter = new StringWriter())
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }))
{
serializer.Serialize(xmlWriter, item, new XmlSerializerNamespaces(new[] { new XmlQualifiedName(string.Empty, string.Empty) }));
}
return stringWriter.ToString();
}
}
Xml output
<root>
<rating city="A" code="A1">A++</rating>
<rating city="B" code="A2">A</rating>
<rating city="C" code="A3">AB</rating>
</root>
Please Change your Class defination to like this:
[XmlTypeAttribute(AnonymousType = true)]
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class root
{
private rootRating[] ratingField;
[XmlElementAttribute("rating")]
public rootRating[] rating
{
get
{
return this.ratingField;
}
set
{
this.ratingField = value;
}
}
}
[XmlTypeAttribute(AnonymousType = true)]
public partial class rootRating
{
private string cityField;
private string codeField;
private string valueField;
[XmlAttributeAttribute()]
public string city
{
get
{
return this.cityField;
}
set
{
this.cityField = value;
}
}
[XmlAttributeAttribute()]
public string code
{
get
{
return this.codeField;
}
set
{
this.codeField = value;
}
}
[XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
//try this
public static XElement SerializeRoot(IEnumerable<root> objRoot)
{
XElement serializedRoot = null;
using (MemoryStream memoryStream = new MemoryStream())
{
using (TextWriter StreamWriter = new StreamWriter(memoryStream))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<root>));
xmlSerializer.Serialize(StreamWriter, objRoot);
serializedRoot = XElement.Parse(Encoding.UTF8.GetString(memoryStream.ToArray()));
}
}
return serializedRoot;
}

XmlSerializer with custom namespace

I want to consume a restful web service with xml. I have to create this template in order to create a valid request:
<WS_IN_GetAccountCredit xmlns="http://schemas.datacontract.org/2004/07/WcfWebService">
<GetAccountCreditParams>
<Password>String content</Password>
<UserName>String content</UserName>
</GetAccountCreditParams>
<WSIdentity>
<WS_PassWord>String content</WS_PassWord>
<WS_UserName>String content</WS_UserName>
</WSIdentity>
</WS_IN_GetAccountCredit>
My serializer method is like this:
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("", "http://schemas.datacontract.org/2004/07/WcfWebService");
XmlSerializer xmlSerializer = new XmlSerializer(instance.GetType());
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, instance, xmlNameSpace); ; return textWriter.ToString();
}
My output looks like this:
<?xml version="1.0" encoding="utf-16"?>
<WS_IN_GetAccountCredit xmlns:xmlns="http://schemas.datacontract.org/2004/07/WcfWebService">
<WSIdentity>
<WS_UserName>String content</WS_UserName>
<WS_PassWord>String content</WS_PassWord>
</WSIdentity>
<GetAccountCreditParams>
<UserName>String content</UserName>
<Password>String content</Password>
</GetAccountCreditParams>
</WS_IN_GetAccountCredit>
As you can see, the namespace and xml version is in wrong format. I also found this, this and this article but non of them could solve my problem.
How can create a valid request?
Here we go:
[XmlRoot(ElementName = "WS_IN_GetAccountCredit", Namespace = "http://schemas.datacontract.org/2004/07/WcfWebService")]
public class WS_IN_GetAccountCredit
{
private WS_IN_WebServiceIdentity wsIdentity;
private WS_IN_GetAccountCreditParams getAccountCreditParams;
public WS_IN_WebServiceIdentity WSIdentity { set { this.wsIdentity = value; } get { return this.wsIdentity; } }
public WS_IN_GetAccountCreditParams GetAccountCreditParams
{
set { this.getAccountCreditParams = value; }
get { return this.getAccountCreditParams; }
}
}
public class WS_IN_WebServiceIdentity
{
public string UserName { get; set; }
public string Password { get; set; }
}
public class WS_IN_GetAccountCreditParams
{
public string UserName { get; set; }
public string Password { get; set; }
}
var namespaces = new XmlSerializerNamespaces();
namespaces.Add("", "http://schemas.datacontract.org/2004/07/WcfWebService");
var ser = new XmlSerializer(typeof(WS_IN_GetAccountCredit));
using (var writer = new StringWriter())
{
ser.Serialize(writer, new WS_IN_GetAccountCredit
{
GetAccountCreditParams = new WS_IN_GetAccountCreditParams { Password = "pass", UserName = "use" },
WSIdentity = new WS_IN_WebServiceIdentity { Password = "pass", UserName = "use" }
},
namespaces);
var xml = writer.ToString();
}
The result is:
<?xml version="1.0" encoding="utf-16"?>
<WS_IN_GetAccountCredit xmlns="http://schemas.datacontract.org/2004/07/WcfWebService">
<WSIdentity>
<UserName>use</UserName>
<Password>pass</Password>
</WSIdentity>
<GetAccountCreditParams>
<UserName>use</UserName>
<Password>pass</Password>
</GetAccountCreditParams>
</WS_IN_GetAccountCredit>

Trying to create a child element in Xml serialization, doesn't show up

I am trying to generate the following XML, and this is also the first time that I ever serialize XML. Could anyone explain to me why my <issuer> element isn't showing up?
What is generated:
<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="02279359-0581-41c7-a66b-199523ac8eab" IssueInstant="18:07:2014 10:41:37 AM" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" />
What I need generated:
<samlp:Response ID="02279359-0581-41c7-a66b-199523ac8eab" IssueInstant="18:07:2014 10:41:37 AM" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" >
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://www.partner.com/sso</saml:Issuer>
</samlp:Response>
What I don't understand is that I marked the Issuer as an XMLElement.
Here is my code.
MySaml.cs
[Serializable]
[XmlRoot(ElementName = "Response", Namespace = "urn:oasis:names:tc:SAML:2.0:protocol", IsNullable = false)]
public class MySaml
{
[XmlAttribute("ID")]
public string ID { get; set; }
[XmlAttribute("Version")]
public const string Version = "2.0";
[XmlAttribute("IssueInstant")]
public string IssueInstant { get; set; }
[XmlAttribute("Destination")]
public const string Destination = "https://www.site.com/SC/SSO/SingleSignOn.aspx";
[XmlAttribute(Namespace = "xmlns", AttributeName = "samlp")]
public const string samlp = "urn:oasis:names:tc:SAML:2.0:protocol";
[XmlElement(Namespace = "urn:oasis:names:tc:SAML:2.0:assertion", ElementName = "Issuer", IsNullable = false)]
public readonly Issuer Issuer = new Issuer();
}
Issuer.cs
[Serializable]
public class Issuer
{
[XmlText]
public const string Text = "https://www.partner.com/sso";
[XmlAttribute(Namespace = "xmlns", AttributeName = "saml")]
public const string saml = "urn:oasis:names:tc:SAML:2.0:assertion";
}
Lastly, The methods I am trying to use to generate the SAML (and pardon the ugly string manipulation there - I am planning to bomb it)
protected void Page_Load(object sender, EventArgs e)
{
GenerateSamlAssertion();
}
private void GenerateSamlAssertion()
{
var response = new MySaml();
response.ID = Guid.NewGuid().ToString();
response.IssueInstant = DateTime.UtcNow.ToString("dd:MM:yyyy hh:mm:ss tt");
SerializeXml(response);
}
public XmlDocument SerializeXml(MySaml mySaml)
{
var xmlSerializerNameSpace = new XmlSerializerNamespaces();
xmlSerializerNameSpace.Add("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
xmlSerializerNameSpace.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
var serializer = new XmlSerializer(typeof(MySaml));
using (var writer = new StringWriter())
{
try
{
serializer.Serialize(writer, mySaml, xmlSerializerNameSpace);
var doc = new XmlDocument();
doc.LoadXml(writer.ToString().Remove(0, writer.ToString().IndexOf("\r\n") + 1));
return doc;
}
finally
{
writer.Close();
}
}
}
I know what I am missing must either be something stupid or something small.
Thanks in Advance :)
In order to be serialized, a field or property must be public, and cannot be readonly.
Here's a worked example:
void Main()
{
Serialize(new ToSerialize());
Serialize(new ToSerialize2());
}
private void Serialize(object o)
{
var serializer = new XmlSerializer(o.GetType());
var ms = new MemoryStream();
serializer.Serialize(ms, o);
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
public class ToSerialize2
{
public ToSerialize2()
{
this.Other = new Other();
}
public Other Other;
}
public class ToSerialize
{
public readonly Other Other = new Other();
}
public class Other
{
}
The output of ToSerialzie misses the "Other" XML element.
<?xml version="1.0"?>
<ToSerialize xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
ToSerialize2 includes it:
<?xml version="1.0"?>
<ToSerialize2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Other />
</ToSerialize2>

XML serialization troubles

so i have this problem i`m trying to serialize my classes to the point that they will look like this:
<orders>
<order>
<ordersID>22070</ordersID>
<ordersTotal>53.00</ordersTotal>
<prod>
<productCount>1</productCount>
<productPrice>2.00</productPrice>
<productPricePromo>0.00</productPricePromo>
<productDiscount>0</productDiscount>
<productName>Шампоан против косопад Loreal Density Advanced 500 мл.</productName>
<productNumber>30055</productNumber>
</prod>
<prod>
<productCount>1</productCount>
<productPrice>6.00</productPrice>
<productPricePromo>0.00</productPricePromo>
<productDiscount>0</productDiscount>
<productName>Маска за суха коса Loreal Интенс Рипер 200 мл.</productName>
<productNumber>30107</productNumber>
</prod>
</order>
</orders>
But whatever i try e end up like this:
<?xml version="1.0" encoding="UTF-8"?>
<orders xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<order>
<order>
<ordersID>0</ordersID>
<ordersTotal>0</ordersTotal>
<products>
<progducts>
<productCount>0</productCount>
<productPrice>0</productPrice>
<productPricePromo>0</productPricePromo>
<productDiscount>0</productDiscount>
<productNumber>0</productNumber>
</progducts>
<progducts>
<productCount>0</productCount>
<productPrice>0</productPrice>
<productPricePromo>0</productPricePromo>
<productDiscount>0</productDiscount>
<productNumber>0</productNumber>
</progducts>
</products>
</order>
</order>
</orders>
The problem is the names of the second and third class i`m using is geting listed as tags aswell inside the xml. So my question is: is there any way around this?
Here is my code aswell.
Classes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace testXML
{
[Serializable]
public class orders
{
private List <order> m_order = new List <order>();
[XmlArrayItem(typeof(order))]
public List<order> order
{
get { return m_order; }
set { m_order = value; }
}
}
[Serializable]
public class order
{
public int ordersID { get; set; }
public double ordersTotal { get; set; }
private List<progducts> prod = new List<progducts>();
[XmlArrayItem(typeof(progducts))]
public List<progducts> products
{
get { return prod; }
set { prod = value; }
}
}
[Serializable]
public class progducts
{
public string productName { get; set; }
public int productCount { get; set; }
public double productPrice { get; set; }
public double productPricePromo { get; set; }
public double productDiscount { get; set; }
public Int64 productNumber { get; set; }
}
}
And here is the execution code:
orders f = new orders();
order or = new order();
progducts p1 = new progducts();
progducts p2 = new progducts();
f.order.Add(or);
or.products.Add(p1);
or.products.Add(p2);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(orders));
TextWriter writer = new StreamWriter("Family.xml");
xmlSerializer.Serialize(writer, f);
writer.Close();
Thank you for any help in advance!
Replace the [XmlArrayItem(typeof(order))] with [XmlElement("order")] and [XmlArrayItem(typeof(progducts))] with [XmlElement("prod")]. That will remove one level when serializing the lists.
Just add another attributes to your property order like this:
[XmlArray("orders")]
[XmlArrayItem("order", typeof(order))]
public List<order> order
{
get { return m_order; }
set { m_order = value; }
}
That should work.
If you use the following classes which were generated using xsd.exe:
using System.Xml.Serialization;
using System;
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class orders
{
private ordersOrder orderField;
public ordersOrder order
{
get
{
return this.orderField;
}
set
{
this.orderField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class ordersOrder
{
private int ordersIDField;
private double ordersTotalField;
private ordersOrderProd[] prodField;
public int ordersID
{
get
{
return this.ordersIDField;
}
set
{
this.ordersIDField = value;
}
}
public double ordersTotal
{
get
{
return this.ordersTotalField;
}
set
{
this.ordersTotalField = value;
}
}
[System.Xml.Serialization.XmlElementAttribute("prod")]
public ordersOrderProd[] prod
{
get
{
return this.prodField;
}
set
{
this.prodField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class ordersOrderProd
{
private int productCountField;
private double productPriceField;
private double productPricePromoField;
private double productDiscountField;
private string productNameField;
private Int64 productNumberField;
public int productCount
{
get
{
return this.productCountField;
}
set
{
this.productCountField = value;
}
}
public double productPrice
{
get
{
return this.productPriceField;
}
set
{
this.productPriceField = value;
}
}
public double productPricePromo
{
get
{
return this.productPricePromoField;
}
set
{
this.productPricePromoField = value;
}
}
public double productDiscount
{
get
{
return this.productDiscountField;
}
set
{
this.productDiscountField = value;
}
}
public string productName
{
get
{
return this.productNameField;
}
set
{
this.productNameField = value;
}
}
public Int64 productNumber
{
get
{
return this.productNumberField;
}
set
{
this.productNumberField = value;
}
}
}
Then the following code:
var orders = new orders
{
order = new ordersOrder
{
ordersID = 1,
ordersTotal = 1,
prod = new ordersOrderProd[]
{
new ordersOrderProd
{
productCount = 1,
productDiscount = 8.4,
productName = "Widget",
productNumber = 987987,
productPrice = 78.9,
productPricePromo = 68.75
}
}
}
};
XmlSerializer xmlSerializer = new XmlSerializer(typeof(orders));
TextWriter writer = new StreamWriter(".\\Family.xml");
xmlSerializer.Serialize(writer, orders);
writer.Close();
Gives you the following output:
<?xml version="1.0" encoding="utf-8"?>
<orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<order>
<ordersID>1</ordersID>
<ordersTotal>1</ordersTotal>
<prod>
<productCount>1</productCount>
<productPrice>78.9</productPrice>
<productPricePromo>68.75</productPricePromo>
<productDiscount>8.4</productDiscount>
<productName>Widget</productName>
<productNumber>987987</productNumber>
</prod>
</order>
</orders>
You can use a serialization attribute to change the names of the XML elements or attributes you want to represent your class structure. See MSDN

Categories

Resources