I use the following code to serialize my class as XML string:
AXMLItem rc = new AXMLItem();
rc.Attributes.Add(new Reports.ReportConfiguration.Questionnaire.FormObjectXMLItem.Attribute { Value = "ddddd" });
MemoryStream fw = new MemoryStream();
var serializer = new XmlSerializer(typeof(AXMLItem ));
using (StringWriter textWriter = new StringWriter())
{
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter))
{
serializer.Serialize(xmlWriter, rc);
}
string myString = textWriter.ToString(); //This is the output as a string
}
that class definition
[XmlType(TypeName = "A")]
public class AXMLItem
{
[XmlType(TypeName = "B")]
public List<Attr> Attrs { get; set; }
[XmlType(TypeName = "C")]
public class Attr
{
[XmlText]
public string Value { get; set; }
}
public AXMLItem()
{
Attrs = new List<Attr>();
}
}
which gives me the following string
<?xml version="1.0" encoding="utf-16"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<B>
<C>ddddd</C>
</B>
</A>
but I need
<?xml version="1.0" encoding="utf-16"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<C>ddddd</C>
</A>
Keep in ming that there can be many <C>...</C> items. How to fix it ?
just add an XmlElement attribute to the collection property:
[XmlElement("C")]
public List<Attr> Attrs { get; set; }
Related
I have below XML stored in a string RequestPassengerXML. How can I deserialize it so that I can get the tags information which I can assign it to my class members.
<?xml version="1.0" encoding="utf-16"?>
<Passenger xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>John Vaz</Name>
<Email>john#gmail.com</Email>
<cardNumber>CB2390VT</cardNumber>
</Passenger>
I have created a class with below details
public class PassengerDetails
{
public PassengerDetails();
public string Name { get; set; }
public string Email { get; set; }
public string CardNumber{ get; set; }
}
public static XElement ToXElement<T>(this object obj)
{
using (var memoryStream = new MemoryStream())
{
using (TextWriter streamWriter = new StreamWriter(memoryStream))
{
var xmlSerializer = new XmlSerializer(typeof(T));
xmlSerializer.Serialize(streamWriter, obj);
return XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));
}
}
}
public static T FromXElement<T>(this XElement xElement)
{
var xmlSerializer = new XmlSerializer(typeof(T));
return (T)xmlSerializer.Deserialize(xElement.CreateReader());
}
Usage:
XElement element = PassengerDetails.ToXElement<PassengerDetails>();
var newMyClass = element.FromXElement<PassengerDetails>();
I need the following output from Pojo classes to Xml.
It's .net 4.6.1, C#.
Problem is in the namespaces and the produced prefixes.
How can I get the node:
<blablubb:Message SOAP-ENV:mustUnderstand="1" xmlns:blablubb="urn:blablubb-com:schemas:blablubb">
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<blablubb:Message SOAP-ENV:mustUnderstand="1" xmlns:blablubb="urn:blablubb-com:schemas:blablubb">
<blablubb:Type>INET_TRANS</blablubb:Type>
<blablubb:Function>RECEIVE_CUSTOMER_ORDER</blablubb:Function>
<blablubb:Sender>CONNECT</blablubb:Sender>
<blablubb:Receiver>CONNECT</blablubb:Receiver>
<blablubb:SentAt>2018-08-30T10:43:37+02:00</blablubb:SentAt>
<blablubb:ExpiresAt>2018-09-30T10:43:37+02:00</blablubb:ExpiresAt>
</blablubb:Message>
</SOAP-ENV:Header>
<SOAP-ENV:Body><ORDERS xmlns="urn:blablubb-com:schemas:inbound_distribution_transactions_create_customer_order_request" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BUYER></BUYER>
<CONTACT_REFERENCE>OAK</CONTACT_REFERENCE>
<EAN_LOCATION_DELIVERY_ADDRESS>10901000</EAN_LOCATION_DELIVERY_ADDRESS>
<CURRENCY_CODE>EUR</CURRENCY_CODE>
<ORDER_DATE>2018-08-27T09:01:01</ORDER_DATE>
<OUR_CUSTOMER_NO>2</OUR_CUSTOMER_NO>
<SUPPLIER_ADDRESS_NO></SUPPLIER_ADDRESS_NO>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Pojos that get serialized:
SoapDocument:
[Serializable]
[XmlRoot("Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[XmlInclude(typeof(SoapHeader))]
public class SoapDocument {
[XmlElement("Header")]
public SoapHeader soapHeader { get; set; }
[XmlElement("Body",typeof(IfsOrdersXmlDocument))]
public object soapBody { get; set; }
}
SoapHeader :
[Serializable]
[XmlRoot("Header")]
[XmlInclude(typeof(SoapMessage))] // include type class IfsOrderLineXmlDocument
public class SoapHeader {
[XmlElement("Message", Namespace = "urn:blablubb-com:schemas:blablubb")]
public SoapMessage soapMessage { get; set; }
}
SoapBody :
[Serializable]
[XmlInclude(typeof(IfsXmlDocument)), XmlInclude(typeof(IfsOrdersXmlDocument))]
[SoapInclude(typeof(IfsXmlDocument)), SoapInclude(typeof(IfsOrdersXmlDocument))]
public class SoapBody {
[XmlElement("Body")]
public IfsXmlDocument soapBody { get; set; }
}
SoapMessage:
[Serializable]
//[XmlType("blablubb")]
[XmlRoot("Message", Namespace = "urn:blablubb-com:schemas:blablubb")]
public class SoapMessage {
[XmlElement("Type")]
public string Type { get; set; }
[XmlElement("Function")]
public string Function { get; set; }
[XmlElement("Sender")]
public string Sender { get; set; }
[XmlElement("Receiver")]
public string Receiver { get; set; }
[XmlElement("SentAt")]
public string SentAt { get; set; }
[XmlElement("ExpiresAt")]
public string ExpiresAt { get; set; }
}
Code that produces the Xml,
So the problem is in the namespaces and prefixes ......
XmlSerializerNamespaces ns = createSoapDocument();
XmlSerializer serializer = new XmlSerializer(typeof(HeinzApi.Soap.SoapDocument), new Type[] { typeof(IfsXmlDocument), typeof(IfsOrdersXmlDocument) });
FileStream fs = new FileStream(xmlTargetPath, FileMode.Create);
serializer.Serialize(fs, soapDocument, ns);
fs.Close();`
And this is what I get:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<Message xmlns="urn:blablubb-com:schemas:blablubb">
<Type>INET_TRANS</Type>
<Function>RECEIVE_CUSTOMER_ORDER</Function>
<Sender>CONNECT</Sender>
<Receiver>CONNECT</Receiver>
<SentAt>2018-01-03T10:43:37+02:00</SentAt>
<ExpiresAt>2018-08-02T10:43:37+02:00</ExpiresAt>
</Message>
</SOAP-ENV:Header>
</SOAP-ENV:Envelope>
This is the createSoapDocument method that adds namespaces to the XmlSerializer Namespaces object:
private XmlSerializerNamespaces createSoapDocument() {
soapMessage.Type = "INET_TRANS";
soapMessage.Function = "RECEIVE_CUSTOMER_ORDER";
soapMessage.Sender = "CONNECT";
soapMessage.Receiver = "CONNECT";
soapMessage.SentAt = "2018-01-03T10:43:37+02:00";
soapMessage.ExpiresAt = "2018-08-02T10:43:37+02:00";
soapHeader.soapMessage = soapMessage;
soapDocument.soapHeader = soapHeader;
//soapDocument.soapBody = (IfsXmlDocument)targetXmlBaseDocument; ;
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
ns.Add("blablubb", "urn:blablubb-com:schemas:blablubb");
return ns;
}
Edit: This is the result after adding the namespaces to XmlSerializerNamespaces:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:blablubb="urn:blablubb-com:schemas:blablubb" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<blablubb:Message>
<blablubb:Type>INET_TRANS</blablubb:Type>
<blablubb:Function>RECEIVE_CUSTOMER_ORDER</blablubb:Function>
<blablubb:Sender>CONNECT</blablubb:Sender>
<blablubb:Receiver>CONNECT</blablubb:Receiver>
<blablubb:SentAt>2018-01-03T10:43:37+02:00</blablubb:SentAt>
<blablubb:ExpiresAt>2018-08-02T10:43:37+02:00</blablubb:ExpiresAt>
</blablubb:Message>
</SOAP-ENV:Header>
</SOAP-ENV:Envelope>
You need to tell the serializer about your blahblubb namespace by adding it to your XmlSerializerNamespaces object.
ns.Add("blablubb", "urn:bla-com:schemas:blablubb");
Don't forget to change
[XmlElement("Body")]
to
[XmlElement("Body", Namespace="urn:bla-com:schemas:blablubb")]
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>
public class PersistableObject
{
public static T Load<T>(string fileName) where T : PersistableObject, new()
{
T result = default(T);
using (XmlReader reader = XmlReader.Create(fileName))
{
result = new XmlSerializer(typeof(T)).Deserialize(reader) as T;
}
return result;
}
public void Save<T>(string fileName) where T : PersistableObject
{
using (FileStream stream = new FileStream(fileName, FileMode.CreateNew))
{
new XmlSerializer(typeof(T)).Serialize(stream, this);
}
}
}
public class DatabaseConfiguration : PersistableObject
{
public string Host { get; set; }
public string Schema { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
I load the XML using the following code:
var configuration = PersistableObject.Load<DatabaseConfiguration>("Database.xml");
However, configuration's properties are null. This is Database.xml:
<?xml version="1.0"?>
<DatabaseConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<Host>localhost</Host>
<Schema>chromium</Schema>
<Username>root</Username>
<Password></Password>
</DatabaseConfiguration>
They stay null for some reason and are not assigned anything. Why's that?
Your Database.xml content is incorrect, specifically its second line that closes the DatabaseConfiguration element.
Replace it with:
<?xml version="1.0"?>
<DatabaseConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<Host>localhost</Host>
<Schema>chromium</Schema>
<Username>root</Username>
<Password></Password>
</DatabaseConfiguration>
I have this existing XML file serving as a template with NO data, just simple nodes... here's a sample:
<?xml version="1.0" encoding="utf-8" ?>
<catalog>
<cd>
<title />
<artist />
<country />
<company />
<price />
<year />
</cd>
</catalog>
Now I have created a similar class for it.
public class Cd
{
public string Title { get; set; }
public string Artist { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Price { get; set; }
public string Year { get; set; }
}
The purpose is this:
Put values on the properties of the var cd = new Cd(); object
Get the existing XML file (template) then pass the values in it (like mapping the object to the existing XML)
Transform the XML template(with values) into XSLT to become HTML
I think that's all.
How to properly do this?
Thanks a lot!
You can use serialization to achieve (1) and (2)
[Serializable]
public class Cd
{
public string Title { get; set; }
public string Artist { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Price { get; set; }
public string Year { get; set; }
}
now in order to create an xml from an object use:
public static string SerializeObject<T>(this T obj)
{
var ms = new MemoryStream();
var xs = new XmlSerializer(obj.GetType());
var xmlTextWriter = new XmlTextWriter(ms, Encoding.UTF8);
xs.Serialize(xmlTextWriter, obj);
string serializedObject = new UTF8Encoding().GetString((((MemoryStream)xmlTextWriter.BaseStream).ToArray()));
return serializedObject;
}
in order to create an object from XML use:
public static T DeserializeObject<T>(this string xml)
{
if (xml == null)
throw new ArgumentNullException("xml");
var xs = new XmlSerializer(typeof(T));
var ms = new MemoryStream(new UTF8Encoding().GetBytes(xml));
try
{
new XmlTextWriter(ms, Encoding.UTF8);
return (T)xs.Deserialize(ms);
}
catch
{
return default(T);
}
finally
{
ms.Close();
}
}
I would create class:
class catalog
{
public CD cd {get;set;}
}
Here is serialization and deserealization helper:
public class Xml
{
public static string Serialize<T>(T value) where T : class
{
if (value == null)
{
return string.Empty;
}
var xmlSerializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
using (var xmlWriter = XmlWriter.Create(stringWriter))
{
xmlSerializer.Serialize(xmlWriter, value);
return stringWriter.ToString();
}
}
public static T Deserialize<T>(string xml)
{
var serializer = new XmlSerializer(typeof(T));
T result;
using (TextReader reader = new StringReader(xml))
{
result = (T) serializer.Deserialize(reader);
}
return result;
}
}
Simply call:
catalog catalogObject = Xml.Deserialize<catalog>(xmlCatalogString);
I suspect you also will need to put some attributes on properties like XmlElement(ElementName = "title") because it is case sensitive.
MSDN