I want to generate following xml output in my C# code :
<?xml version="1.0" encoding="utf-16"?>
<CallConnectReq Xmlns="urn:interno-com:ns:a9c" reqId="9" msgNb="2">
<LocalCallId>0</LocalCallId>
</CallConnectReq>
right now I am achieving this as follows:
var xnameSpace = new XmlSerializerNamespaces();
xnameSpace.Add("Xmlns", Constants.XmlNameSpaceValue);
var xmlSerializer = new XmlSerializer(objToSerialize.GetType());
var stringWriter = new StringWriter();
xmlSerializer.Serialize(stringWriter, objToSerialize, xnameSpace);
return stringWriter.ToString().**Replace("xmlns:","");**
But I want to remove "xmlns:" tag without using Replace() method.
Is there any way to do it?
To add just the default namespace:
var xnameSpace = new XmlSerializerNamespaces();
xnameSpace.Add("", "urn:interno-com:ns:a9c");
var ser = new XmlSerializer(typeof (CallConnectRequest));
ser.Serialize(destination, new CallConnectRequest(), xnameSpace);
with:
[XmlRoot("CallConnectReq", Namespace = "urn:interno-com:ns:a9c")]
public class CallConnectRequest {}
If you genuinely want Xmlns (which, to restate, I strongly believe is a typo of xmlns, and if not: is a bad choice in that it adds confusion), then:
var xnameSpace = new XmlSerializerNamespaces();
xnameSpace.Add("", "");
var ser = new XmlSerializer(typeof (CallConnectRequest));
ser.Serialize(destination, new CallConnectRequest {
RequestId = 9,
MessageNumber = 2,
LocalCallId = 0
}, xnameSpace);
using:
[XmlRoot("CallConnectReq")]
public class CallConnectRequest {
[XmlAttribute("Xmlns"), Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public string XmlNamespace {
get { return "urn:interno-com:ns:a9c";} set { }
}
[XmlAttribute("reqId")]
public int RequestId { get; set; }
[XmlAttribute("msbNb")]
public int MessageNumber { get; set; }
[XmlElement("LocalCallId")]
public int LocalCallId { get; set; }
}
which writes:
<?xml version="1.0" encoding="ibm850"?>
<CallConnectReq Xmlns="urn:interno-com:ns:a9c" reqId="9" msbNb="2">
<LocalCallId>0</LocalCallId>
</CallConnectReq>
Related
I am trying to get my output in a specified format for example
Expected
<?xml version="1.0"?>
<xml>
<JournalEntries>
<JournalEntry>
<Field1>SampleOne</Field1>
<Field2>SampleTwo</Field2>
</JournalEntry>
<JournalEntry>
<Field1>SampleOne</Field1>
<Field2>SampleTwo</Field2>
</JournalEntry>
</JournalEntries>
</xml>
My Current Output:
<?xml version="1.0"?>
<xml>
<JournalEntry>
<Field1>SampleOne</Field1>
<Field2>SampleTwo</Field2>
</JournalEntry>
<JournalEntry>
<Field1>SampleOne</Field1>
<Field2>SampleTwo</Field2>
</JournalEntry>
</xml>
So essentially I need to add another root ? in a sense so that there is one JournalEntries at the start and end. Since a group of entries consists of multiple Entry
[XmlRoot(ElementName = "xml")]
public class JournalDocument
{
public JournalDocument()
{
}
public JournalDocument(UnProcessedDocument input)
{
input.Body.ForEach(o =>
{
JournalEntries.Add(new JournalEntry
{
Field1 = "SampleOne"
Field2 = "SampleTwo"
}); ;
});
}
[XmlElement("JournalEntry")]
public List<JournalEntry> JournalEntries { get; set; } = new List<JournalEntry>();
}
public class JournalEntry
{
public string Field1 {get;set;}
public string Field2 {get;set}
}
I don't know if i have my defined root and elements in the correct place and i've tried moving them around but to no luck.. for example i tried putting [XmlRoot(ElementName = "JournalEntries")] just above my JournalEntry class
I prefer using IXmlSerializable.
It's more flexible to me and gives you much more control over the serialization.
Example:
public class JournalDocument : IXmlSerializable
{
public XmlSchema GetSchema() => null;
public void WriteXml(XmlWriter writer)
{
writer.WriteStartDocument();
writer.WriteStartElement("xml");
writer.WriteStartElement("JournalEntries")
if(this.JournalEntries.Count != 0)
{
foreach(JournalEntrie entrie in this.JournalEntries)
{
writer.WriteStartElement("JournalEntrie");
writer.WriteElementString("Field1", entrie.Field1)
writer.WriteElementString("Field2", entrie.Field2)
writer.WriteEndElement();
}
}
writer.WriteEndElement();
writer.WriteEndDocument(); // close all open elements
}
public void ReadXml(XmlReader reader)
{
while(reader.Read())
{
if(reader.NodeType == XmlNodeType.element)
{
JournalEntrie entrie;
switch(reader.Name)
{
case "JournalEntrie":
entrie = new JournalEntrie();
break;
case "Field1":
entire.Field1 = reader.ReadElementContentAsString();
break;
// Now make this for every element.
}
}
}
}
}
Although IXMLSerializer was an option I ended up creating an extension method instead
public static string Serialize<T>(this object obj)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
var xmlWriterSettings = new XmlWriterSettings() { Indent = true };
XmlSerializer serializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
using var writer = XmlWriter.Create(stringWriter, xmlWriterSettings);
serializer.Serialize(writer, obj, ns);
writer.Close();
return stringWriter.ToString();
}
And my main code I could keep the same with [XmlRoot(ElementName = "xml")] but just remove the [XmlElement("JournalEntry")]
This ended up solving my issue.
with the programming is this:
As a result I want to have this:
<rootprefix:rootname
noPrefix="attribute with no prefix"
firstprefix:attrOne="first atrribute"
secondprefix:attrTwo="second atrribute with different prefix">
...other elements...
</rootprefix:rootname>
The way to do this by coding is:
NameTable nt = new NameTable();
nt.Add("key");
XmlNamespaceManager ns = new XmlNamespaceManager(nt);
ns.AddNamespace("firstprefix", "fp");
ns.AddNamespace("secondprefix", "sp");
root.SetAttribute("attrOne", ns.LookupPrefix("fp"), "1st attribute");
root.SetAttribute("attrTwo", ns.LookupPrefix("sp"), "2nd with different prefix");
But I want to do this using attributes of types above of the class declaration.
For eg: [XmlType(Namespace = "bb:aaaa")] or something else.
How can I do this?
Edit:
My class something like this:
[XmlRoot("Node", Namespace="http://flibble")]
public class MyType {
[XmlElement("chileNode")]
public string Value { get; set; }
}
And I want to have this result:
<?xml version="1.0" encoding="ibm857"?>
<myNamespace:Node xmlns:myNamespace="http://hede.com" />
Without writing this code:
static class Program
{
static void Main()
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("myNamespace", "http://hede.com");
XmlSerializer xser = new XmlSerializer(typeof(MyType));
xser.Serialize(Console.Out, new MyType(), ns);
}
}
With some attribute like this:
[XmlRoot("Node", Namespace="http://hede.com", NamespacePrefix="myNamespace")]
public class MyType {
[XmlElement("chileNode")]
public string Value { get; set; }
}
But I couldn't find a way putting "myNamespace" prefix in front of xml tag.
I'm serializing a class like below
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
StringWriter sw = new StringWriter();
XmlSerializer serializer1 = new XmlSerializer(typeof(List<student>), new XmlRootAttribute("Response"));
XmlTextWriter xmlWriter = new XmlTextWriter(sw);
serializer1.Serialize(xmlWriter, ls, namespaces);
sw.ToString()
The result string below
<?xml version="1.0" encoding="utf-16"?>
<Response><student><name>xxx</name></student></Response>
but, How can i add an attribute to the root element(Response)?
like below one
<?xml version="1.0" encoding="utf-16"?>
<Response status="1"><student><name>xxx</name></student></Response>
You just need to mark that property of the class with XmlAttribute, i.e.
class MyClass{
[XmlAttribute("status")]
public string ErrorStatus { get; set; }
}
Edit:
Just realised you are serializing the list directly. Put your list inside a parent class, Response, and add the above attribute to this Response class, then serialise the Response object.
Hope this helps.
You can create another object that contains the list, and then create a property to add the attribute to the root node.
The trick is to preface the list in this new class with an explicit type assignment to the Student type to avoid having your list nested within another parent node.
[XmlType(TypeName = "Response")]
public class ResponseObject
{
[XmlAttribute("status")]
public string file { get; set; }
[XmlElement("Student", Type = typeof(Student))]
public List<Student> studentList { get; set; }
}
Your code would then look like the following
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
StringWriter sw = new StringWriter();
XmlSerializer serializer1 = new XmlSerializer(typeof(ResponseObject));
XmlTextWriter xmlWriter = new XmlTextWriter(sw);
//Creating new object and assign the existing list and status
ResponseObject resp = new ResponseObject();
resp.studentList = ls;
resp.status = 1;
//Serialize with the new object
serializer1.Serialize(xmlWriter, resp, namespaces);
sw.ToString()
I have following exercise to do ...
I shall get following xml-file ...
<?xml version="1.0" encoding="UTF-8"?>
<Mitarbeiterstatistik xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Mitarbeiter>
<Vorname>Horst</Vorname>
<Nachname>Schneider</Nachname>
<Id>1</Id>
</Mitarbeiter>
<Mitarbeiter>
<Vorname>Tanja</Vorname>
<Nachname>Lindner</Nachname>
<Id>2</Id>
</Mitarbeiter>
</Mitarbeiterstatistik>
Now I tried following steps ...
I made a class Mitarbeiter!
public class Mitarbeiter
{
private string vorname;
private string nachname;
private int id;
public Mitarbeiter()
{
}
public Mitarbeiter(string vorname, string nachname, int id)
{
this.vorname = vorname;
this.nachname = nachname;
this.id = id;
}
public string Vorname
{
get { return vorname; }
set { vorname = value; }
}
public string Nachname
{
get { return nachname; }
set { nachname = value; }
}
public int Id
{
get { return id; }
set { id = value; }
}
}
Then I made a class Mitarbeiterstatistik with a list for Mitarbeiter objects ...
[XmlRoot("Mitarbeiterstatistik")]
public class Mitarbeiterstatistik
{
private List<Mitarbeiter> list = new List<Mitarbeiter>();
[XmlArray("List")]
public List<Mitarbeiter> List
{
get { return list; }
set { list = value; }
}
}
My Main-Class looks like ...
class Program
{
static void Main(string[] args)
{
Mitarbeiterstatistik maStatistik = new Mitarbeiterstatistik();
Mitarbeiter ma1 = new Mitarbeiter("Horst", "Schneider", 1);
Mitarbeiter ma2 = new Mitarbeiter("Tanja", "Lindner", 2);
maStatistik.List.Add(ma1);
maStatistik.List.Add(ma2);
XmlSerializer serializer = new XmlSerializer(typeof(Mitarbeiterstatistik));
XmlWriter writer = XmlWriter.Create(#"D:\test.xml");
serializer.Serialize(writer, maStatistik);
writer.Close();
}
}
Now I got following result ...
<?xml version="1.0" encoding="UTF-8"?>
<Mitarbeiterstatistik xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
**<List>**
<Mitarbeiter>
<Vorname>Horst</Vorname>
<Nachname>Schneider</Nachname>
<Id>1</Id>
</Mitarbeiter>
<Mitarbeiter>
<Vorname>Tanja</Vorname>
<Nachname>Schneider</Nachname>
<Id>2</Id>
</Mitarbeiter>
**</List>**
</Mitarbeiterstatistik>
No I have an Element "List" in my Xml-file ... :-)
What can I do against my problem ...
Is there only the possibility to define only a Mitarbeiter class and NO Mitarbeiterstatistik-Class?
Maybe as following?
List<Mitarbeiter> list = new List<Mitarbeiter>();
Mitarbeiter ma1 = new Mitarbeiter("Horst", "Schneider", 1);
Mitarbeiter ma2 = new Mitarbeiter("Tanja", "Lindner", 2);
list.Add(ma1);
list.Add(ma2);
XmlSerializer serializer = new XmlSerializer(typeof(List<Mitarbeiter>), new XmlRootAttribute("Mitarbeiterstatistik"));
XmlWriter writer = XmlWriter.Create(#"D:\test.xml");
serializer.Serialize(writer, list);
writer.Close();
Or is there a chance to keep my Mitarbeiterstatistik-Class??? And disable my List-Element???
If you want to try Linq To Xml:
XDocument xDoc = new XDocument(new XElement("Mitarbeiterstatistik"));
foreach (var mitarbeiter in list)
{
xDoc.Root.Add(
new XElement("Mitarbeiter",
new XElement("Vorname" ,mitarbeiter.Vorname ),
new XElement("Nachname" ,mitarbeiter.Nachname ),
new XElement("Id" ,mitarbeiter.Id )));
}
xDoc.Save(#"d:\test.xml");
You can get out of attribute "List" (as i undestand your question correctly) using [XmlElement] with name of element you want to get instead of [XmlArray]:
[XmlRoot("Mitarbeiterstatistik")]
public class Mitarbeiterstatistik
{
private List<Mitarbeiter> list = new List<Mitarbeiter>();
[XmlElement("Mitarbeiter")]
public List<Mitarbeiter> List {get; set;}
}
How can i serialize Instance of College to XML using Linq?
class College
{
public string Name { get; set; }
public string Address { get; set; }
public List<Person> Persons { get; set; }
}
class Person
{
public string Gender { get; set; }
public string City { get; set; }
}
You can't serialize with LINQ. You can use XmlSerializer.
XmlSerializer serializer = new XmlSerializer(typeof(College));
// Create a FileStream to write with.
Stream writer = new FileStream(filename, FileMode.Create);
// Serialize the object, and close the TextWriter
serializer.Serialize(writer, i);
writer.Close();
Not sure why people are saying you can't serialize/deserialize with LINQ. Custom serialization is still serialization:
public static College Deserialize(XElement collegeXML)
{
return new College()
{
Name = (string)collegeXML.Element("Name"),
Address = (string)collegeXML.Element("Address"),
Persons = (from personXML in collegeXML.Element("Persons").Elements("Person")
select Person.Deserialize(personXML)).ToList()
}
}
public static XElement Serialize(College college)
{
return new XElement("College",
new XElement("Name", college.Name),
new XElement("Address", college.Address)
new XElement("Persons", (from p in college.Persons
select Person.Serialize(p)).ToList()));
);
Note, this probably isn't the greatest approach, but it's answering the question at least.
You can't use LINQ. Look at the below code as an example.
// This is the test class we want to
// serialize:
[Serializable()]
public class TestClass
{
private string someString;
public string SomeString
{
get { return someString; }
set { someString = value; }
}
private List<string> settings = new List<string>();
public List<string> Settings
{
get { return settings; }
set { settings = value; }
}
// These will be ignored
[NonSerialized()]
private int willBeIgnored1 = 1;
private int willBeIgnored2 = 1;
}
// Example code
// This example requires:
// using System.Xml.Serialization;
// using System.IO;
// Create a new instance of the test class
TestClass TestObj = new TestClass();
// Set some dummy values
TestObj.SomeString = "foo";
TestObj.Settings.Add("A");
TestObj.Settings.Add("B");
TestObj.Settings.Add("C");
#region Save the object
// Create a new XmlSerializer instance with the type of the test class
XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass));
// Create a new file stream to write the serialized object to a file
TextWriter WriteFileStream = new StreamWriter(#"C:\test.xml");
SerializerObj.Serialize(WriteFileStream, TestObj);
// Cleanup
WriteFileStream.Close();
#endregion
/*
The test.xml file will look like this:
<?xml version="1.0"?>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SomeString>foo</SomeString>
<Settings>
<string>A</string>
<string>B</string>
<string>C</string>
</Settings>
</TestClass>
*/
#region Load the object
// Create a new file stream for reading the XML file
FileStream ReadFileStream = new FileStream(#"C:\test.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
// Load the object saved above by using the Deserialize function
TestClass LoadedObj = (TestClass)SerializerObj.Deserialize(ReadFileStream);
// Cleanup
ReadFileStream.Close();
#endregion
// Test the new loaded object:
MessageBox.Show(LoadedObj.SomeString);
foreach (string Setting in LoadedObj.Settings)
MessageBox.Show(Setting);
you have to use the XML serialization
static public void SerializeToXML(College college)
{
XmlSerializer serializer = new XmlSerializer(typeof(college));
TextWriter textWriter = new StreamWriter(#"C:\college.xml");
serializer.Serialize(textWriter, college);
textWriter.Close();
}
You can use that if you needed XDocument object after serialization
DataClass dc = new DataClass();
XmlSerializer x = new XmlSerializer(typeof(DataClass));
MemoryStream ms = new MemoryStream();
x.Serialize(ms, dc);
ms.Seek(0, 0);
XDocument xDocument = XDocument.Load(ms); // Here it is!
I'm not sure if that is what you want, but to make an XML-Document out of this:
College coll = ...
XDocument doc = new XDocument(
new XElement("College",
new XElement("Name", coll.Name),
new XElement("Address", coll.Address),
new XElement("Persons", coll.Persons.Select(p =>
new XElement("Person",
new XElement("Gender", p.Gender),
new XElement("City", p.City)
)
)
)
);