Add namespaces to serialized xml - c#

I've got a pretty nasty problem with xml serialization - I need to add some special information to the resulting xml-file:
Currently, it looks like
<?xml version="1.0" encoding="iso-8859-1"?>
<ORDER_LIST>
<ORDER version="1.0" xmlns="http://www.opentrans.org/XMLSchema/1.0">... shortened ...</ORDER>
<ORDER version="1.0" xmlns="http://www.opentrans.org/XMLSchema/1.0">... shortened ...</ORDER>
<ORDER version="1.0" xmlns="http://www.opentrans.org/XMLSchema/1.0">... shortened ...</ORDER>
</ORDER_LIST>
but it should look like
<?xml version="1.0" encoding="iso-8859-1"?>
<ORDER_LIST>
<ORDER xmlns="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" type="standard">... shortened ...</ORDER>
<ORDER xmlns="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" type="standard">... shortened ...</ORDER>
<ORDER xmlns="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" type="standard">... shortened ...</ORDER>
</ORDER_LIST>
The additional namespace (xmlns:xsi) and the xsi:schemaLocation / type attributes should be added to the result.
Actually my code is:
[XmlTypeAttribute(Namespace="http://www.opentrans.org/XMLSchema/1.0")]
public class OrderContainer
{
[XmlElementAttribute("ORDER")]
public List<ORDER> orderList;
}
---- snip ----
string xmlString;
XmlWriterSettings settings = new XmlWriterSettings()
{
Encoding = Encoding.GetEncoding("ISO-8859-1"),
Indent = true,
IndentChars = "\t",
NewLineChars = Environment.NewLine,
ConformanceLevel = ConformanceLevel.Document,
};
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
var testOrder = new ORDER();
var orderContainer = new OrderContainer();
orderContainer.orderList = new List<ORDER>();
orderContainer.orderList.Add(testOrder);
XmlSerializer serializer = new XmlSerializer(typeof(List<ORDER>), new XmlRootAttribute("ORDER_LIST"));
using (MemoryStream ms = new MemoryStream())
{
using (XmlWriter writer = XmlTextWriter.Create(ms, settings))
serializer.Serialize(writer, orderList, ns);
xmlString = Encoding.ASCII.GetString(ms.ToArray());
}
Console.WriteLine(xmlString);
It works really fine - except for the namespaces and attributes on the ORDER elements.
Background-information: The ORDER class is created from the openTrans-definition (opentrans_order_1_0_all_in_one.xsd).
It's been translated into C# classes using Xsd2Code (Xsd2Code).
Because of the automatic generation, adorning the class with attributes is not easily possible - I guess?
Thanks for any hint!
(Edited some information)

I know its a little late to reply to this question, but nonetheless I am answering in case someone in need stumbles upon this question.
I order to add namespaces you need to use this class: System.Xml.Serialization. XmlSerializerNamespaces, which I see in the problem code that it has been defined.
Following is the syntax that I have used to add namespaces while dealing with the xCBL Xml Schema:
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces xmlns; //Defined as the Field of the class you want to serialize
//Defined in the Constructor
xmlns = new XmlSerializerNamespaces();
xmlns.Add("core", "rrn:org.xcbl:schemas/xcbl/v4_0/core/core.xsd");
This will add the namespace in the generated Xml like this:
xmlns:core="rrn:org.xcbl:schemas/xcbl/v4_0/core/core.xsd"

What it should look like is:
<?xml version="1.0" encoding="iso-8859-1"?>
<ORDER_LIST xmlns:trans="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" >
<trans:ORDER type="standard" >... shortened ...</ORDER>
<trans:ORDER type="standard" >... shortened ...</ORDER>
<trans:ORDER type="standard" >... shortened ...</ORDER>
</ORDER_LIST>
I'm not familar with xsd2code, but if you were hand coding, you need to put attributes.
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.opentrans.org/XMLSchema/1.0")]
[System.Xml.Serialization.XmlElementAttribute("Order")]
public class Order() {
String Type
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.opentrans.org/XMLSchema/1.0")]
[System.Xml.Serialization.XmlRootAttribute("OrderList", Namespace="http://www.opentrans.org/XMLSchema/1.0", IsNullable=false)]
public class OrderList() {
List<Orders>
}

try this. it's a libary to create or read opentrans documents!
http://opentrans.wordpress.com/

Related

Can you Serialize inside a set of Attributes by Set of Attributes?

I want a serialize a set of attributes all together to an XML file in a loop that runs. This loop runs within a set of folders . According to my Current implementation It only shows the last set of Attributes.
Here is my Current code ,
Student obj = JsonConvert.DeserializeObject < StudentModel (File.ReadAllText(file));
string Name = studentModel.name;
string number = studentModel.number;
string testPath = rootDirectory;
XmlSerializer serializer = new XmlSerializer(typeof(StudentModel));
System.IO.StreamWriter writer = new System.IO.StreamWriter(testPath + "\\Test.xml");
serializer.Serialize(writer, studentModel);
writer.Close();
My Current output is
<?xml version="1.0" encoding="utf-8"?>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Max</name>
<number>1</number>
</StudentModel>
Required output is
<?xml version="1.0" encoding="utf-8"?>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Max</name>
<number>1</number>
</StudentModel>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Amy</name>
<number>2</number>
</StudentModel>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Jack</name>
<number>3</number>
</StudentModel>
It seems to me, that what you want to do is serialize a list (or array) of StudentModel to an xml. Currently you are only serializing one instance of StudentModel and overwrite the resulting xml each iteration of the loop, leaving you with the last item. What you can do, is to create a class with a List() of StudentModel as Property and serialize that class instance, not needing a loop anymore.
The List property in your new class would then look something like this:
[XmlArray("StudentModels"), XmlArrayItem(typeof(StudentModel), ElementName = "StudentModel")]
public List<StudentModel> StudentModelList{ get; set; }

How to set namespace on XDocument

I need to acсess xml file. But xml have base namespace whith prefix m:
This is my code, but it do not working, write NullRefference exeptions:
var fileКс = XDocument.Load(somePath);
var allDescrioptions = fileКс.Root.Element("formulas").Elements("formula").ToList();
This is part of xml file:
<?xml version="1.0" encoding="utf-8" ?>
<m:math xmlns:m="http://www.kontur-extern.ru/ФНС 4.0/math.xsd">
<m:formulas>
<m:formula target="#ПрибУб" match="/Файл/Документ/Прибыль/РасчНал" source="Лист 02/стр.060">
</m:formula>
</m:formulas>
</m:math>
I think need to specify namespace, but I don't know how
You can use XNamespace as follow :
XNamespace m = "http://www.kontur-extern.ru/ФНС 4.0/math.xsd";
var fileКс = XDocument.Load(somePath);
var allDescrioptions = fileКс.Root.Element(m+"formulas").Elements(m+"formula").ToList();

How do I get an attribute with namespace?

<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Element xsi:Attribute="Test"></Element>
</Root>
I'm trying to read the "xsi:Attribute" attribute; the code is like this:
var doc = XDocument.Load(new StringReader(xmlText));
var node = doc.Root.Descendants().First();
XNamespace myNamespace = "xsi";
var attribute = node.Attributes(myNamespace + "Attribute").First();
It throws a "Sequence contains no elements" exception in the last line. What am I doing wrong?
You need to use the actual namespace, not "xsi", which is just a local lookup within the XML file itself for the real namespace:
XNamespace myNamespace = "http://www.w3.org/2001/XMLSchema-instance";
Try this (I believe its more generic):
XNamespace myNamespace = doc.Root.GetNamespaceOfPrefix("xsi");

Change order of xmlnamespace

I was working on Xml serialization. My class is
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
[XmlInclude(typeof(Url))]
public class UrlSet
{
[XmlAttribute("schemaLocation", Namespace = XmlSchema.InstanceNamespace)]
public string xsiSchemaLocation = "http://www.sitemaps.org/schemas/sitemap/0.9" +
"http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd";
}
Tried adding
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Output its giving to me is
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
I need to have
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
I also tried adding empty namespace, But that adds prefix q to every element in xml. I also want to know if that order really matters as I am going to submit generated sitemap to google
Any solutions?

Serialize XML and append new elements to XML file

I have created a XML class using XSD2Code from my XML Schema. The class having a method SaveToFile. So when I am trying to add new elements and save it to the XML file it overwrites the entire content.
Does anyone have idea how to insert elements(append to the XML) to the XML file via Serialization.
eg:
<?xml version="1.0" encoding="utf-8"?>
<root>
<element>content1</element>
</root>
If this is the XML file I need to add an element and the resulting should come as like below using Serialization.
<?xml version="1.0" encoding="utf-8"?>
<root>
<element>content1</element>
<element>content2</element>
</root>
Your request would seem to be resolvable by adding another item into your List collection.
MyTypeFromXmlSchema myType = new MyTypeFromXmlSchema();
myType.MyElementItems = new List<MyElementItem>();
myType.MyElementItems.Add { new MyElementItem { value = "value1" } };
myType.MyElementItems.Add { new MyElementItem { value = "value2" } };
Then serialize type using XmlSerializer.

Categories

Resources