Xml .NET : Remove ArrayOfXmlElement and XmlElement - c#

I created a .NET class for XML serialization
[Serializable()]
[XmlRoot("documents")]
public class BdfXmlData
{
[XmlElement("document")]
public List<XmlElement> Documents { get; set; }
public BdfXmlData()
{
Documents = new List<XmlElement>();
}
}
When I try to serialize an object, I get with this tree:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfXmlElement xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<XmlElement>
<documents>
<document>
...
<document>
<documents>
</XmlElement>
</ArrayOfXmlElement>
How can I have the following three?
<?xml version="1.0" encoding="utf-8"?>
<documents>
<document>
...
<document>
<documents>
Thanks in advance.
The code to serialize my class is the following:
public static string GetSerializedObject<T>(T t)
{
using (MemoryStream stream = new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stream, t);
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream))
return reader.ReadToEnd();
}
}

I think you can at least simplify your xml-code:
<ArrayOfdocuments xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<documents>
<document>
...
<document>
<documents>
</ArrayOfdocuments>
The "XmlElement" element can be left out.

Surely you are serialising an array of BdfXmlData
in pseudo code
BdfXmlData[] dataInArray = new [] {new BdfXmlData()};
GetSerializedObject(dataInArray)
would produce what you have whereas,
in pseudo code..
BdfXmlData data = new BdfXmlData();
GetSerializedObject(data)
should give you what you want!

Exact, I serialise the Documents collection :
SerializationHelper.GetSerializedObject(xmlRootData.Documents);
In fact, I receive some XmlElement with this tree :
<document>
...
<document>
and I add these elements to my List "Documents".
xmlRootData.Documents.Add(xmlData);
When I serialise my final object (BdfXmlData), the xml contains 2 documents tags and 2 document tags
string xmlData = SerializationHelper.GetSerializedObject(xmlRootData);
<documents xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<document>
<documents>
<document>
</document>
<documents>
</document>
</documents>

Related

How to add xsi:noNamespaceSchemaLocation to Serializer

I build an XML Document which needs to be validated against a xsd file. Thus I need a reference to the xsd file in the root element of the xml. So far I use this C# Code:
var ser = new XmlSerializer(typeof(myspecialtype));
XmlSerializerNamespaces MainNamespace = new XmlSerializerNamespaces();
MainNamespace.Add("xlink", "http://www.w3.org/1999/xlink");
MainNamespace.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
using (XmlWriter w = XmlWriter.Create(#"C:\myxmlfile.xml"))
{
w.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"utils/somexsl.xsl\"");
ser.Serialize(w, LeBigObject, HauptNs);
}
The resulting Xml begins like this:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="utils/somexsl.xsl"?>
<caddy-xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlVersion="03.07.00">
but I need this:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="utils/somexsl.xsl"?>
<caddy-xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlVersion="03.07.00" xsi:noNamespaceSchemaLocation="utils/theveryimportant.xsd">
I came across "CreateAttribute" here: Add Namespace to an xml root node c# but I can't put it together with the Serializer. Thank you!
I was pointed to the solution here:
https://social.msdn.microsoft.com/Forums/en-US/e43585c6-181b-4449-8806-b07f82681a2a/how-to-include-xsinonamespaceschemalocation-in-the-xml?forum=asmxandxml
I added this to my class:
[XmlAttribute("noNamespaceSchemaLocation", Namespace = XmlSchema.InstanceNamespace)]
public string attr = "utils/theveryimportant.xsd";
and it works.

Issue on saving the XML file after editing it

I have an XML file with some data on it..for example
<?xml version="1.0" encoding="utf-8"?>
<CreateAndSendMessageRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.communisis.com/lv">
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
Now i want to replace POLICY REFERENCE value with some dummy data. I am able to do that but now i have to save it as a new file with a different file name..
How can i achieve that..
For reference i am giving my code.
XmlDocument doc = new XmlDocument();
doc.Load(filepath);
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
var item =node.Item(0);
string value = item.FirstChild.Value;
string nevalue = value.Replace(value, "Test123");
doc.DocumentElement.;
doc.Save(#"C:\Test\file.xml");
The xml wasn't valid.
Anyway, this is how to make it work:
Xml file:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Code:
XmlDocument doc = new XmlDocument();
doc.Load("bho.xml");
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
node[0].InnerText = "Test123";
doc.Save("file.xml");
Result xml:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>Test123</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Hope it helps you ^^

Using xmlwriter to custom write XML

I am trying to use xmlwriter to customize my xml file. I have tried using a class to serialize to xml but it does not seem to work. My goal is to have multiple namespace definitions within the "AddO" element, with each element under the messages having a prefix.
Click event:
XmlWriterSettings objSetting = new XmlWriterSettings();
objSetting.Indent = true;
objSetting.NewLineOnAttributes = true;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
using (XmlWriter objWriter = XmlWriter.Create(sb, objSetting))
{
//Request
objWriter.WriteStartDocument();
objWriter.WriteStartElement("Request");
objWriter.WriteStartElement("SName");
objWriter.WriteValue("AocD");
objWriter.WriteEndElement();
objWriter.WriteStartElement("Message");
//objWriter.WriteStartElement("pd", "AddO", "www.google.com");
objWriter.WriteStartElement("pd", "AddO", "www.google.com");
objWriter.WriteStartElement("aoc","CaseD");
objWriter.WriteStartElement("CaseA");
objWriter.WriteStartElement("DocE");
objWriter.WriteEndElement();
objWriter.WriteEndElement();
objWriter.WriteEndElement();
objWriter.WriteEndElement();//CaseD End
objWriter.WriteEndElement();//Message End
objWriter.WriteEndElement();//Request End
objWriter.WriteEndDocument();
File.WriteAllText(Server.MapPath("~/images/test.xml"), sb.ToString());
I get this XML Result:
<?xml version="1.0" encoding="utf-16"?>
<Request>
<SName>AocD</SName>
<Message>
<iepd:AddO xmlns:iepd="www.google.com">
<aoc xmlns="CaseD">
<CaseA>
<DocE>
</DocE>
</CaseA>
</aoc>
</iepd:AddO>
</Message>
</Request>
Trying to get:
<?xml version="1.0" encoding="utf-16"?>
<Request>
<SName>AocD</SName>
<Message>
<iepd:AddO xmlns:iepd="www.google.com" xmlns:a="www.goo.com" xmlns:b="www.gle.com" xmlns:d="www.le.com">
<a:CaseD">
<b:CaseA>
<d:DocE>
</d:DocE>
</b:CaseA>
</a:CaseD>
</iepd:AddO>
</Message>
</Request>

Deserialization XML in a List

The Application serializes a List to xml:
<?xml version="1.0"?>
<Tools xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Tool>
<Name>test1</Name>
<Path>C:\Program Files\FreePDF_XP\fpmailer.exe</Path>
</Tool>
<Tool>
<Name>test2</Name>
<Path>C:\Program Files\FreePDF_XP\fpassist.exe</Path>
</Tool>
<Tool>
<Name>test3</Name>
<Path>C:\Program Files\FreePDF_XP\ShellMail.exe</Path>
</Tool>
</Tools>
If I'm don't on the wrong way I must create new Objects and add them to a list:
Tool tool = new Tool();
XmlSerializer deserializer = new XmlSerializer(typeof(List<Tool>));
using (var reader = new StreamReader(#Start.userConfigurePath + "\\config.xml"))
{
tool = (Tool)deserializer.Deserialize(reader);
reader.Close();
}
toolList.Add(tool);
}
In the result there isn't a Object in the List. How can I deserialize the serialized objects in the xml in a List? Could it be that there is something wrong at the code for derisalization?
Edit:
Something seems to be wrong with my xml declaration (XML File Error 2,2). That I don't understand because i create the xml document on this way:
XmlDocument toolConfig = new XmlDocument();
XmlNode myRoot;
myRoot = toolConfig.CreateElement("Tool");
toolConfig.AppendChild(myRoot);
It should be
toolList = (List<Tool>)deserializer.Deserialize(reader);

Getting InvalidOperationException when Deserializing in C#

I'm using an XML based .config file for storing some records.
my XML is below:
<?xml version="1.0" encoding="utf-8"?>
<Data_List xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Configuration>
<Name>1st Week</Name>
<Binary>
<Field>field1</Field>
<Version>1.0</Version>
</Binary>
<Binary>
<Field>field2</Field>
<Version>2.0</Version>
</Binary>
</Configuration>
<Configuration>
<Name>2nd Week</Name>
<Binary>
<Field>field1</Field>
<Version>2.0</Version>
</Binary>
<Binary>
<Field>field2</Field>
<Version>4.0</Version>
</Binary>
</Configuration>
</Data_List>
I'm using C# code as follows:
public Binary
{
public String Field;
public String Version;
}
public Configuration
{
public String Name;
public List<Binary> Binary_List = new List<Binary>();
public GetfromXML()
{
List<Configuration> lists = new List<Configuration>();
TextReader reader = new StreamReader("Data_List.config");
XmlSerializer serializer = new XmlSerializer(typeof(List<Configuration>));
lists=(List<Configuration>)serializer.Deserialize(reader);
reader.Close();
}
I'm getting an exception saying "There's an error in XML document(2,2)".
Can anyone pls help?
I think the problem is that your model is not well structurized. In other words, serializer does not know how to read your .xml.
Your xml is wrong. When you have List< T > there would be an:
<ArrayOfT></ArrayOfT>
in .XML. Here is how you need to do it!
First, try using xml attributes from System.Xml.Serialization(i.e. [XmlArray()])
It would be better that you use FileStream instead of just pointing out URI
using(var filestream = new FileStream(//your uri, FIleMode.Open)
{
}
Use properties instead of variables. Because later on you may want to bind.
Example of my code how i managed to solve that issue:
public ServiceMap Deserialize()
{
ServiceMap serviceMap = new ServiceMap();
try
{
using (var fileStream = new FileStream(Settings.ServiceMapPath, FileMode.Open))
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
using (XmlReader reader = XmlReader.Create(fileStream, settings))
{
serviceMap = _serializer.Deserialize(reader) as ServiceMap;
}
}
}
catch (FileNotFoundException)
{
MessageBox.Show("File 'ServiceMap.xml' could not be found!");
}
return serviceMap;
}
My ServiceMap class:
[XmlRoot("ServiceMap")]
public class ServiceMap
{
[XmlArray("Nodes")]
[XmlArrayItem("Node")]
public List<Node> Nodes = new List<Node>();
[XmlArray("Groups")]
[XmlArrayItem("Group")]
public List<Group> Groups = new List<Group>();
[XmlArray("Categories")]
[XmlArrayItem("Category")]
public List<Category> Categories = new List<Category>();
}
EDIT: My XML:
<?xml version="1.0" encoding="utf-8"?>
<ServiceMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http:// www.w3.org/2001/XMLSchema">
<Nodes>
<Node Name="Predrag">
<Children>
<Child>dijete1</Child>
<Child>dijete2</Child>
<Child>dijete3</Child>
<Child>dijete4</Child>
</Children>
<Parents>
<Parent>roditelj1</Parent>
<Parent>roditelj2</Parent>
<Parent>roditelj3</Parent>
</Parents>
<Group Name="Grupa" />
<Category Name="Kategorija" />
</Node>
<Node Name="Tami">
<Children>
<Child>dijete1</Child>
<Child>dijete2</Child>
</Children>
<Parents>
<Parent>roditelj1</Parent>
</Parents>
<Group Name="Grupa2" />
<Category Name="Kategorija2" />
</Node>

Categories