I used xmltocsharp site to create the class helper to deserialize an specific XML, but is not working, and the problem is in the root element. This is the root element (RESP_HDR and RESP_BODY were collapsed):
<?xml version="1.0" encoding="UTF-8"?>
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
+ <SII:RESP_HDR>
+ <SII:RESP_BODY>
</SII:RESPUESTA>
And this is the root element class generated by xmltocsharp site:
[XmlRoot(ElementName = "RESPUESTA", Namespace = "http://www.sii.cl/XMLSchema")]
public class RESPUESTA
{
[XmlElement(ElementName = "RESP_HDR", Namespace = "http://www.sii.cl/XMLSchema")]
public RESP_HDR RESP_HDR { get; set; }
[XmlElement(ElementName = "RESP_BODY", Namespace = "http://www.sii.cl/XMLSchema")]
public RESP_BODY RESP_BODY { get; set; }
[XmlAttribute(AttributeName = "SII", Namespace = "http://www.w3.org/2000/xmlns/")]
public string SII { get; set; }
}
The issue is that the class fails to deserialize a XML like the showed before, but success with this:
<?xml version="1.0" encoding="UTF-8"?>
<RESPUESTA xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SII="http://www.sii.cl/XMLSchema" xmlns="http://www.sii.cl/XMLSchema">
+ <SII:RESP_HDR>
+ <SII:RESP_BODY>
</RESPUESTA>
The difference is in the namespaces, even if a create the object and serialize it, this will be the result. So, what should be changed in the class to make it work with the original XML?
UPDATE:
Looking closer I found the really issue, is in the root element still, but I notice the missing xmlns prefix in the root tag, how can I set it in the helper class?
EDIT:
This is an XML sample from the service response:
<?xml version="1.0" encoding="UTF-8"?>
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_HDR>
<SII:ESTADO>0</SII:ESTADO>
<SII:GLOSA/>
</SII:RESP_HDR>
<SII:RESP_BODY>
<DATOS_CONSULTA>
<RUT>80182144-3</RUT>
<TIPO_CONSULTA>DEUDOR</TIPO_CONSULTA>
<DESDE_DDMMAAAA>01042017</DESDE_DDMMAAAA>
<HASTA_DDMMAAAA>01052017</HASTA_DDMMAAAA>
</DATOS_CONSULTA>
<CESION>
<VENDEDOR>11455447-9</VENDEDOR>
<ESTADO_CESION>Cesion Vigente</ESTADO_CESION>
<DEUDOR>80182144-3</DEUDOR>
<MAIL_DEUDOR/>
<TIPO_DOC>33</TIPO_DOC>
<NOMBRE_DOC>Factura Electronica</NOMBRE_DOC>
<FOLIO_DOC>107</FOLIO_DOC>
<FCH_EMIS_DTE>2017-04-04</FCH_EMIS_DTE>
<MNT_TOTAL>3324860</MNT_TOTAL>
<CEDENTE>11455447-9</CEDENTE>
<RZ_CEDENTE>JHON DOE</RZ_CEDENTE>
<MAIL_CEDENTE>jjdoe#gmail.com</MAIL_CEDENTE>
<CESIONARIO>762327129-7</CESIONARIO>
<RZ_CESIONARIO>capital sa</RZ_CESIONARIO>
<MAIL_CESIONARIO>xcap#capital.com</MAIL_CESIONARIO>
<FCH_CESION>2017-04-05 13:15</FCH_CESION>
<MNT_CESION>3324860</MNT_CESION>
<FCH_VENCIMIENTO>2017-06-04</FCH_VENCIMIENTO>
</CESION>
<CESION>
<VENDEDOR>11455447-9</VENDEDOR>
<ESTADO_CESION>Cesion Vigente</ESTADO_CESION>
<DEUDOR>80182144-3</DEUDOR>
<MAIL_DEUDOR/>
<TIPO_DOC>33</TIPO_DOC>
<NOMBRE_DOC>Factura Electronica</NOMBRE_DOC>
<FOLIO_DOC>34</FOLIO_DOC>
<FCH_EMIS_DTE>2017-03-01</FCH_EMIS_DTE>
<MNT_TOTAL>1725500</MNT_TOTAL>
<CEDENTE>11455447-9</CEDENTE>
<RZ_CEDENTE>JOE DOE</RZ_CEDENTE>
<MAIL_CEDENTE>jd#gmail.com</MAIL_CEDENTE>
<CESIONARIO>762327129-7</CESIONARIO>
<RZ_CESIONARIO>Capital S.A.</RZ_CESIONARIO>
<MAIL_CESIONARIO>jcap#capital.com</MAIL_CESIONARIO>
<FCH_CESION>2017-04-05 17:27</FCH_CESION>
<MNT_CESION>1725500</MNT_CESION>
<FCH_VENCIMIENTO>2017-03-01</FCH_VENCIMIENTO>
</CESION>
</SII:RESP_BODY>
</SII:RESPUESTA>
So far the only way that I can make it work is with a really ugly solution, this should not be considered as an answer to the problem!!.
//Query service to obtain XML response
string xmlResponse = siiClient.QueryDocuments(documentsRequest);
//Replace RESPUESTA tags in the XML response, remove the prefix SII
var replacedXML = xmlResponse .Replace("SII:RESPUESTA", "RESPUESTA" );
//Load XML string into XmlDocument
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(replacedXML);
//Add missing namespaces
xDoc.DocumentElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
xDoc.DocumentElement.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
xDoc.DocumentElement.SetAttribute("xmlns", "http://www.sii.cl/XMLSchema");
//Now deserialization will work
var documentResponse = xDoc.ParseXML<RESPUESTA>();
The ideal solution will take the XML Response and deserialize it directly without any preprocessing like:
//Query service to obtain XML response
string xmlResponse = siiClient.QueryDocuments(documentsRequest);
//ParseXML is an extension method, it can handle an string or an XmlDocument
var documentResponse = xmlResponse.ParseXML<RESPUESTA>();
Note: ParseXML is based on #Damian's answer
I took your xml:
<?xml version="1.0" encoding="UTF-8"?>
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_HDR/>
<SII:RESP_BODY/>
</SII:RESPUESTA>
I took you class:
[XmlRoot(ElementName = "RESPUESTA", Namespace = "http://www.sii.cl/XMLSchema")]
public class RESPUESTA
{
[XmlElement(ElementName = "RESP_HDR", Namespace = "http://www.sii.cl/XMLSchema")]
public RESP_HDR RESP_HDR { get; set; }
[XmlElement(ElementName = "RESP_BODY", Namespace = "http://www.sii.cl/XMLSchema")]
public RESP_BODY RESP_BODY { get; set; }
[XmlAttribute(AttributeName = "SII", Namespace = "http://www.w3.org/2000/xmlns/")]
public string SII { get; set; }
}
public class RESP_HDR { }
public class RESP_BODY { }
Just added two empty class stub.
Try System.Xml.Serialization.XmlSerializer:
RESPUESTA respuesta;
var xs = new XmlSerializer(typeof(RESPUESTA));
using (var fs = new FileStream("test.xml", FileMode.Open))
respuesta = (RESPUESTA)xs.Deserialize(fs);
It works! I don't understand how and why it does not work for you.
Related
I do have a problem with serialization of a namespaces. As my code show below my logic fills the structure of my dictionary, serializes it and puts into a string variable. I use this variable to load into XMLDocument and after that I do add the namespaces. But since they are added after the serialization process the namespaces are set in UTF8? Should I add namespaces before serialization? If yes, how can I do it properly?
///Dictionary
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace TestXML
{
[Serializable]
[XmlRoot(ElementName = "Root")]
public class XMLSchema: Serialization
{
[XmlElement(ElementName = "Element1")]
public XMLElement1 Element1 { get; set; }
[XmlElement(ElementName = "Element2")]
public XMLElement2 Element2 { get; set; }
}
}
///Serialization class
public class Utf8StringWriter : StringWriter
{
// Use UTF8 encoding
public override Encoding Encoding
{
get { return new UTF8Encoding(false); }
}
}
public string Serialize()
{
var xmlserializer = new XmlSerializer(this.GetType());
var Utf8StringWriter = new Utf8StringWriter();
var xns = new XmlSerializerNamespaces();
xns.Add(string.Empty, string.Empty);
using (var writer = XmlWriter.Create(Utf8StringWriter))
{
xmlserializer.Serialize(writer, this, xns);
return Utf8StringWriter.ToString();
}
}
///create xml
str xml;
[...] my logic to add data into elements
XmlDocument doc = new XmlDocument();
xml = XMLSchema.Serialize();
doc.LoadXml(xml);
XmlElement root = doc.getNamedElement("Root");
root.SetAttribute("xmlns:etd", "http://google.com");
root.SetAttribute("xmlns:xsi", "http://google.com");
root.SetAttribute("xmlns", "http://google.com");
doc.AppendChild(root);
doc.Save(path);
Edit. Adding provided sample.
<?xml version="1.0" encoding="UTF-8"?> <XMLSample xmlns="http://crd.gov.pl/wzor/" xmlns:xsi="http://www.w3.org/2001/" xmlns:etd="http://crd.gov.pl/xml/schematy/">
So to give you an example (based on your sample):
[XmlRoot("XMLSample", Namespace = "http://crd.gov.pl/wzor/")]
public class XmlSample
{
[XmlElement]
public string Element1 { get; set; }
[XmlElement(Namespace = "http://crd.gov.pl/xml/schematy/")]
public string Element2 { get; set; }
}
Here, the root has the namespace http://crd.gov.pl/wzor/. Element1 inherits that namespace (as none is specified). Element2 has the namespace http://crd.gov.pl/xml/schematy/.
When this is serialised, the serialiser will use the root namespace as the default, so there's no need to explicitly set this. You can set the others to use the prefixes as defined in your sample:
var xsn = new XmlSerializerNamespaces();
xsn.Add("xsi", "http://www.w3.org/2001/");
xsn.Add("etd", "http://crd.gov.pl/xml/schematy/");
You can see this fiddle for a demo, the output is:
<?xml version="1.0" encoding="utf-8"?>
<XMLSample xmlns:xsi="http://www.w3.org/2001/" xmlns:etd="http://crd.gov.pl/xml/schematy/" xmlns="http://crd.gov.pl/wzor/">
<Element1>foo</Element1>
<etd:Element2>bar</etd:Element2>
</XMLSample>
Note that Element2 uses the prefix configured for its namespace.
I have XML file which have some tags with dot(.), now i am using "StringWriter"
to Map XML data with C#, but i am not able to handle XML tags which have dot(.) in tag name like:- "Customer.Name", how can i map this with C# class.
I had give XmlElement with my class model, but still i am not getting values map with my class.
Can any one give me suggestion.
[XmlElement(ElementName = "PARENTNAME")]
public string PARENTNAME { get; set; } //This is perfect mapped
[XmlElement(ElementName = "DISPLAYCONTACT.CONTACTNAME")]
public string DISPLAYCONTACTCONTACTNAME { get; set; } // This is not mapped
[XmlElement(ElementName = "DISPLAYCONTACT.COMPANYNAME")]
public string DISPLAYCONTACTCOMPANYNAME { get; set; }
Convert XML to C#
XmlDocument doc = new XmlDocument();
doc.LoadXml(customerString);
StringWriter sw = new StringWriter();
XmlTextWriter xw = new XmlTextWriter(sw);
doc.WriteTo(xw);
String XmlString = sw.ToString();
string xmlToJson = JsonConvert.SerializeXmlNode(doc);
var deserialized = JsonConvert.SerializeXmlNode(doc);
var customer = new CusGetResIn();
customer= JsonConvert.DeserializeObject<CusGetResIn>(deserialized);
Also Tried:-
XmlSerializer serializer = new XmlSerializer(typeof(CusGetResIn));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(XmlString));
CusGetResIn resultingMessage = (CusGetResIn)serializer.Deserialize(memStream);
XML:-
<?xml version="1.0" encoding="UTF-8"?>
<response>
<control>
<status>success</status>
<senderid>Intacct_ISB</senderid>
<controlid>17/12/2018</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<status>success</status>
<userid>vinit1</userid>
<companyid>FASTMORE-trial</companyid>
<locationid></locationid>
<sessiontimestamp>2018-12-19T00:41:15-08:00</sessiontimestamp>
</authentication>
<result>
<status>success</status>
<function>readByQuery</function>
<controlid>testFunctionId</controlid>
<data listtype="customer" count="31" totalcount="31" numremaining="0" resultId="">
<customer>
<RECORDNO>5</RECORDNO>
<CUSTOMERID>CUST-00101</CUSTOMERID>
<NAME>Sun Microsystems - EBC</NAME>
<ENTITY>CCUST-00101</ENTITY>
<PARENTKEY></PARENTKEY>
<PARENTID></PARENTID>
<PARENTNAME></PARENTNAME>
<DISPLAYCONTACT.CONTACTNAME>Sun Microsystems - EBC(CCUST-00101)</DISPLAYCONTACT.CONTACTNAME>
<DISPLAYCONTACT.COMPANYNAME>Sun Microsystems - EBC</DISPLAYCONTACT.COMPANYNAME>
<DISPLAYCONTACT.PREFIX></DISPLAYCONTACT.PREFIX>
<DISPLAYCONTACT.FIRSTNAME></DISPLAYCONTACT.FIRSTNAME>
<DISPLAYCONTACT.LASTNAME></DISPLAYCONTACT.LASTNAME>
<DISPLAYCONTACT.INITIAL></DISPLAYCONTACT.INITIAL>
<DISPLAYCONTACT.PRINTAS>Sun Microsystems - Executive Briefing Center</DISPLAYCONTACT.PRINTAS>
<DISPLAYCONTACT.TAXABLE>true</DISPLAYCONTACT.TAXABLE>
<DISPLAYCONTACT.TAXGROUP></DISPLAYCONTACT.TAXGROUP>
<DISPLAYCONTACT.PHONE1></DISPLAYCONTACT.PHONE1>
<DISPLAYCONTACT.PHONE2></DISPLAYCONTACT.PHONE2>
<DISPLAYCONTACT.CELLPHONE></DISPLAYCONTACT.CELLPHONE>
<DISPLAYCONTACT.PAGER></DISPLAYCONTACT.PAGER>
<DISPLAYCONTACT.FAX></DISPLAYCONTACT.FAX>
<DISPLAYCONTACT.EMAIL1>sevans#intacct.com</DISPLAYCONTACT.EMAIL1>
<DISPLAYCONTACT.EMAIL2></DISPLAYCONTACT.EMAIL2>
<DISPLAYCONTACT.URL1></DISPLAYCONTACT.URL1>
<DISPLAYCONTACT.URL2></DISPLAYCONTACT.URL2>
<DISPLAYCONTACT.VISIBLE>true</DISPLAYCONTACT.VISIBLE>
<DISPLAYCONTACT.MAILADDRESS.ADDRESS1>1245 Williams Lane</DISPLAYCONTACT.MAILADDRESS.ADDRESS1>
<DISPLAYCONTACT.MAILADDRESS.ADDRESS2></DISPLAYCONTACT.MAILADDRESS.ADDRESS2>
<DISPLAYCONTACT.MAILADDRESS.CITY>San Jose</DISPLAYCONTACT.MAILADDRESS.CITY>
<DISPLAYCONTACT.MAILADDRESS.STATE>CA</DISPLAYCONTACT.MAILADDRESS.STATE>
<DISPLAYCONTACT.MAILADDRESS.ZIP>95112</DISPLAYCONTACT.MAILADDRESS.ZIP>
<DISPLAYCONTACT.MAILADDRESS.COUNTRY>USA</DISPLAYCONTACT.MAILADDRESS.COUNTRY>
<DISPLAYCONTACT.MAILADDRESS.COUNTRYCODE></DISPLAYCONTACT.MAILADDRESS.COUNTRYCODE>
<DISPLAYCONTACT.MAILADDRESS.LATITUDE></DISPLAYCONTACT.MAILADDRESS.LATITUDE>
<DISPLAYCONTACT.MAILADDRESS.LONGITUDE></DISPLAYCONTACT.MAILADDRESS.LONGITUDE>
<DISPLAYCONTACT.STATUS>active</DISPLAYCONTACT.STATUS>
<TERMNAME>2/10 Net30</TERMNAME>
<TERMVALUE>2:10:1#30#1%:W:</TERMVALUE>
<CUSTREPID>EMP-002</CUSTREPID>
<CUSTREPNAME>Joanna Drake</CUSTREPNAME>
<RESALENO></RESALENO>
<TAXID></TAXID>
<CREDITLIMIT></CREDITLIMIT>
<TOTALDUE>3525172.72</TOTALDUE>
<COMMENTS></COMMENTS>
<ACCOUNTLABEL></ACCOUNTLABEL>
<ARACCOUNT>4000</ARACCOUNT>
<ARACCOUNTTITLE>Sales</ARACCOUNTTITLE>
<LAST_INVOICEDATE>10/01/2012</LAST_INVOICEDATE>
<LAST_STATEMENTDATE></LAST_STATEMENTDATE>
<DELIVERY_OPTIONS>Print#~#E-Mail</DELIVERY_OPTIONS>
<TERRITORYID></TERRITORYID>
<SHIPPINGMETHOD>Delivery</SHIPPINGMETHOD>
<CUSTTYPE>Corporate</CUSTTYPE>
<GLGRPKEY></GLGRPKEY>
<GLGROUP></GLGROUP>
<PRICESCHEDULE></PRICESCHEDULE>
<DISCOUNT></DISCOUNT>
<PRICELIST></PRICELIST>
<VSOEPRICELIST></VSOEPRICELIST>
<CURRENCY></CURRENCY>
<CONTACTINFO.CONTACTNAME></CONTACTINFO.CONTACTNAME>
<CONTACTINFO.PREFIX></CONTACTINFO.PREFIX>
<CONTACTINFO.FIRSTNAME></CONTACTINFO.FIRSTNAME>
<CONTACTINFO.INITIAL></CONTACTINFO.INITIAL>
<CONTACTINFO.LASTNAME></CONTACTINFO.LASTNAME>
<CONTACTINFO.COMPANYNAME></CONTACTINFO.COMPANYNAME>
<CONTACTINFO.PRINTAS></CONTACTINFO.PRINTAS>
<CONTACTINFO.PHONE1></CONTACTINFO.PHONE1>
<CONTACTINFO.PHONE2></CONTACTINFO.PHONE2>
<CONTACTINFO.CELLPHONE></CONTACTINFO.CELLPHONE>
<CONTACTINFO.PAGER></CONTACTINFO.PAGER>
<CONTACTINFO.FAX></CONTACTINFO.FAX>
<CONTACTINFO.EMAIL1></CONTACTINFO.EMAIL1>
<CONTACTINFO.EMAIL2></CONTACTINFO.EMAIL2>
<CONTACTINFO.URL1></CONTACTINFO.URL1>
<CONTACTINFO.URL2></CONTACTINFO.URL2>
<CONTACTINFO.VISIBLE></CONTACTINFO.VISIBLE>
<CONTACTINFO.MAILADDRESS.ADDRESS1></CONTACTINFO.MAILADDRESS.ADDRESS1>
<CONTACTINFO.MAILADDRESS.ADDRESS2></CONTACTINFO.MAILADDRESS.ADDRESS2>
<CONTACTINFO.MAILADDRESS.CITY></CONTACTINFO.MAILADDRESS.CITY>
<CONTACTINFO.MAILADDRESS.STATE></CONTACTINFO.MAILADDRESS.STATE>
<CONTACTINFO.MAILADDRESS.ZIP></CONTACTINFO.MAILADDRESS.ZIP>
<CONTACTINFO.MAILADDRESS.COUNTRY></CONTACTINFO.MAILADDRESS.COUNTRY>
<CONTACTINFO.MAILADDRESS.COUNTRYCODE></CONTACTINFO.MAILADDRESS.COUNTRYCODE>
<SHIPTO.CONTACTNAME></SHIPTO.CONTACTNAME>
<SHIPTO.PREFIX></SHIPTO.PREFIX>
<SHIPTO.FIRSTNAME></SHIPTO.FIRSTNAME>
<SHIPTO.INITIAL></SHIPTO.INITIAL>
<SHIPTO.LASTNAME></SHIPTO.LASTNAME>
<SHIPTO.COMPANYNAME></SHIPTO.COMPANYNAME>
<SHIPTO.PRINTAS></SHIPTO.PRINTAS>
<SHIPTO.TAXABLE></SHIPTO.TAXABLE>
<SHIPTO.TAXGROUP></SHIPTO.TAXGROUP>
<SHIPTO.PHONE1></SHIPTO.PHONE1>
<SHIPTO.PHONE2></SHIPTO.PHONE2>
<SHIPTO.CELLPHONE></SHIPTO.CELLPHONE>
<SHIPTO.PAGER></SHIPTO.PAGER>
<SHIPTO.FAX></SHIPTO.FAX>
<SHIPTO.EMAIL1></SHIPTO.EMAIL1>
<SHIPTO.EMAIL2></SHIPTO.EMAIL2>
<SHIPTO.URL1></SHIPTO.URL1>
<SHIPTO.URL2></SHIPTO.URL2>
<SHIPTO.VISIBLE></SHIPTO.VISIBLE>
<SHIPTO.MAILADDRESS.ADDRESS1></SHIPTO.MAILADDRESS.ADDRESS1>
<SHIPTO.MAILADDRESS.ADDRESS2></SHIPTO.MAILADDRESS.ADDRESS2>
<SHIPTO.MAILADDRESS.CITY></SHIPTO.MAILADDRESS.CITY>
<SHIPTO.MAILADDRESS.STATE></SHIPTO.MAILADDRESS.STATE>
<SHIPTO.MAILADDRESS.ZIP></SHIPTO.MAILADDRESS.ZIP>
<SHIPTO.MAILADDRESS.COUNTRY></SHIPTO.MAILADDRESS.COUNTRY>
<SHIPTO.MAILADDRESS.COUNTRYCODE></SHIPTO.MAILADDRESS.COUNTRYCODE>
<BILLTO.CONTACTNAME></BILLTO.CONTACTNAME>
<BILLTO.PREFIX></BILLTO.PREFIX>
<BILLTO.FIRSTNAME></BILLTO.FIRSTNAME>
<BILLTO.INITIAL></BILLTO.INITIAL>
<BILLTO.LASTNAME></BILLTO.LASTNAME>
<BILLTO.COMPANYNAME></BILLTO.COMPANYNAME>
<BILLTO.PRINTAS></BILLTO.PRINTAS>
<BILLTO.TAXABLE></BILLTO.TAXABLE>
<BILLTO.TAXGROUP></BILLTO.TAXGROUP>
<BILLTO.PHONE1></BILLTO.PHONE1>
<BILLTO.PHONE2></BILLTO.PHONE2>
<BILLTO.CELLPHONE></BILLTO.CELLPHONE>
<BILLTO.PAGER></BILLTO.PAGER>
<BILLTO.FAX></BILLTO.FAX>
<BILLTO.EMAIL1></BILLTO.EMAIL1>
<BILLTO.EMAIL2></BILLTO.EMAIL2>
<BILLTO.URL1></BILLTO.URL1>
<BILLTO.URL2></BILLTO.URL2>
<BILLTO.VISIBLE></BILLTO.VISIBLE>
<BILLTO.MAILADDRESS.ADDRESS1></BILLTO.MAILADDRESS.ADDRESS1>
<BILLTO.MAILADDRESS.ADDRESS2></BILLTO.MAILADDRESS.ADDRESS2>
<BILLTO.MAILADDRESS.CITY></BILLTO.MAILADDRESS.CITY>
<BILLTO.MAILADDRESS.STATE></BILLTO.MAILADDRESS.STATE>
<BILLTO.MAILADDRESS.ZIP></BILLTO.MAILADDRESS.ZIP>
<BILLTO.MAILADDRESS.COUNTRY></BILLTO.MAILADDRESS.COUNTRY>
<BILLTO.MAILADDRESS.COUNTRYCODE></BILLTO.MAILADDRESS.COUNTRYCODE>
<STATUS>active</STATUS>
<ONETIME>false</ONETIME>
<CUSTMESSAGEID></CUSTMESSAGEID>
<ONHOLD>false</ONHOLD>
<PRCLST_OVERRIDE>C</PRCLST_OVERRIDE>
<OEPRCLSTKEY></OEPRCLSTKEY>
<OEPRICESCHEDKEY></OEPRICESCHEDKEY>
<ENABLEONLINECARDPAYMENT>true</ENABLEONLINECARDPAYMENT>
<ENABLEONLINEACHPAYMENT>true</ENABLEONLINEACHPAYMENT>
<VSOEPRCLSTKEY></VSOEPRCLSTKEY>
<WHENMODIFIED>12/18/2018 16:07:40</WHENMODIFIED>
<ARINVOICEPRINTTEMPLATEID></ARINVOICEPRINTTEMPLATEID>
<OEQUOTEPRINTTEMPLATEID></OEQUOTEPRINTTEMPLATEID>
<OEORDERPRINTTEMPLATEID></OEORDERPRINTTEMPLATEID>
<OELISTPRINTTEMPLATEID></OELISTPRINTTEMPLATEID>
<OEINVOICEPRINTTEMPLATEID></OEINVOICEPRINTTEMPLATEID>
<OEADJPRINTTEMPLATEID></OEADJPRINTTEMPLATEID>
<OEOTHERPRINTTEMPLATEID></OEOTHERPRINTTEMPLATEID>
<WHENCREATED>01/01/1970 00:00:00</WHENCREATED>
<CREATEDBY></CREATEDBY>
<MODIFIEDBY>1</MODIFIEDBY>
<OBJECTRESTRICTION>Unrestricted</OBJECTRESTRICTION>
<DISPLAYCONTACTKEY>38</DISPLAYCONTACTKEY>
<CONTACTKEY></CONTACTKEY>
<SHIPTOKEY></SHIPTOKEY>
<BILLTOKEY></BILLTOKEY>
<CUSTREPKEY>2</CUSTREPKEY>
<SHIPVIAKEY>1</SHIPVIAKEY>
<TERRITORYKEY></TERRITORYKEY>
<TERMSKEY>1</TERMSKEY>
<ACCOUNTLABELKEY></ACCOUNTLABELKEY>
<ACCOUNTKEY>25</ACCOUNTKEY>
<CUSTTYPEKEY>1</CUSTTYPEKEY>
<PRICESCHEDULEKEY></PRICESCHEDULEKEY>
<OFFSETGLACCOUNTNO></OFFSETGLACCOUNTNO>
<OFFSETGLACCOUNTNOTITLE></OFFSETGLACCOUNTNOTITLE>
<ADVBILLBY></ADVBILLBY>
<ADVBILLBYTYPE></ADVBILLBYTYPE>
<SUPDOCID></SUPDOCID>
<MEGAENTITYKEY></MEGAENTITYKEY>
<MEGAENTITYID></MEGAENTITYID>
<MEGAENTITYNAME></MEGAENTITYNAME>
<RESTRICTEDLOCATIONS></RESTRICTEDLOCATIONS>
<RESTRICTEDDEPARTMENTS></RESTRICTEDDEPARTMENTS>
</customer></data>
</result>
</operation>
</response>
Please help me.
Quick test shows XmlSerializer can handle this pretty easily
Test class:
[XmlRoot]
public class Test
{
[XmlElement(ElementName="Foo.Alpha")]
public string Alpha {get;set;}
[XmlElement(ElementName="Foo.Beta")]
public string Beta {get;set;}
}
Example method:
private static void Main()
{
var src = #"<Test>
<Foo.Alpha>value 1</Foo.Alpha>
<Foo.Beta>value 2</Foo.Beta>
</Test>";
using (var sreader = new StringReader(src))
using (var reader = XmlReader.Create(sreader))
{
var serializer = new XmlSerializer(typeof(Test));
var test = (Test)serializer.Deserialize(reader);
Console.WriteLine(test.Alpha);
Console.WriteLine(test.Beta);
}
}
Update: since the XML document you are processing is very large, you should consider what you actually need to do. If you need to manipulate the entire document as objects then the approach taken in JP Hellemons's answer may be the way to go. If you are only interested in certain fields, then it may be better to load the XML into an XDocument or XmlDocument and extract the fields you are interested in from that, or even write a forward-only parser using XmlReader to do the same thing.
I have pasted your XML in an XMLFile1.xml and pasted it in Visual Studio to generate classes, so this will be a lot of autogenerated code... warning
could not fit auto gen code...
Body is limited to 30000 characters; you entered 93977
Full code here:
https://pastebin.com/VxzNUjsv
Smaller version:
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<RECORDNO>5</RECORDNO>
<CUSTOMERID>CUST-00101</CUSTOMERID>
<PARENTNAME>parent</PARENTNAME>
<DISPLAYCONTACT.CONTACTNAME>Sun Microsystems - EBC(CCUST-00101)</DISPLAYCONTACT.CONTACTNAME>
<DISPLAYCONTACT.COMPANYNAME>Sun Microsystems - EBC</DISPLAYCONTACT.COMPANYNAME>
</customer>
and C# code:
class Program
{
static void Main(string[] args)
{
using (var sreader = new StringReader(File.ReadAllText(#"C:\Users\JP\source\repos\soXmlParsing\soXmlParsing\XMLFile1.xml")))
using (var reader = XmlReader.Create(sreader))
{
var serializer = new XmlSerializer(typeof(customer));
var test = (customer)serializer.Deserialize(reader);
Console.WriteLine(test.PARENTNAME);
Console.WriteLine(test.DISPLAYCONTACTCONTACTNAME);
}
}
}
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class customer
{
private byte rECORDNOField;
private string cUSTOMERIDField;
private string pARENTNAMEField;
private string dISPLAYCONTACTCONTACTNAMEField;
private string dISPLAYCONTACTCOMPANYNAMEField;
/// <remarks/>
public byte RECORDNO
{
get
{
return this.rECORDNOField;
}
set
{
this.rECORDNOField = value;
}
}
/// <remarks/>
public string CUSTOMERID
{
get
{
return this.cUSTOMERIDField;
}
set
{
this.cUSTOMERIDField = value;
}
}
/// <remarks/>
public string PARENTNAME
{
get
{
return this.pARENTNAMEField;
}
set
{
this.pARENTNAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("DISPLAYCONTACT.CONTACTNAME")]
public string DISPLAYCONTACTCONTACTNAME
{
get
{
return this.dISPLAYCONTACTCONTACTNAMEField;
}
set
{
this.dISPLAYCONTACTCONTACTNAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("DISPLAYCONTACT.COMPANYNAME")]
public string DISPLAYCONTACTCOMPANYNAME
{
get
{
return this.dISPLAYCONTACTCOMPANYNAMEField;
}
set
{
this.dISPLAYCONTACTCOMPANYNAMEField = value;
}
}
}
I searched and tried some attributes but none of them worked for my below scenario:
public class ObjSer
{
[XmlElement("Name")]
public string Name
{
get; set;
}
}
//Code to serialize
var obj = new ObjSer();
obj.Name = "<tag1>Value</tag1>";
var stringwriter = new System.IO.StringWriter();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
serializer.Serialize(stringwriter, obj);
Output would be as follows:
<ObjSer><Name><tag1>Value</tag1></Name></ObjSer>
But I need output as:
<ObjSer><Name><tag1>Value</tag1></Name></ObjSer>
Scenario 2: In some cases I need to set:
obj.Name = "Value";
Is there any attribute or method I can override to make it possible?
You can't with default serializer. XmlSerializer does encoding of all values during serialization.
If you want your member to hold xml value, it must be XmlElement. Here is how you can accomplish it
public class ObjSer
{
[XmlElement("Name")]
public XmlElement Name
{
get; set;
}
}
var obj = new ObjSer();
// <-- load xml
var doc = new XmlDocument();
doc.LoadXml("<tag1>Value</tag1>");
obj.Name = doc.DocumentElement;
// --> assign the element
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
serializer.Serialize(Console.Out, obj);
Output:
<?xml version="1.0" encoding="IBM437"?>
<ObjSer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>
<tag1>Value</tag1>
</Name>
</ObjSer>
UPDATE:
In case if you want to use XElement instead of XmlElement, here is sample on how to do it
public class ObjSer
{
[XmlElement("Name")]
public XElement Name
{
get; set;
}
}
static void Main(string[] args)
{
//Code to serialize
var obj = new ObjSer();
obj.Name = XDocument.Parse("<tag1>Value</tag1>").Document.FirstNode as XElement;
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
serializer.Serialize(Console.Out, obj);
}
No, you can't. It is the natural and usual behaviour of the xml serializer. The serializer doesn't have to handle within the XML strings. So, it escapes the xml as expected.
You should decode the escaped string again while deserializing it.
If you want to add dynamically elements in the XML I suggest you to use Linq to XML and you can create tag1 or another kind of elements easily.
I would suggest serializing to an XDocument then converting that to a string and manually unescaping the desired part and writing it to a file. I would say this would give you the least headache it shouldn't be more than a couple lines of code. If you need it I can provide some code example if needed.
I found one more way of changing the type
public class NameNode
{
public string tag1
{
get; set;
}
[XmlText]
public string Value
{
get; set;
}
}
public class ObjSer
{
[XmlElement("Name")]
public NameNode Name
{
get; set;
}
}
To set value of Name:
var obj = new ObjSer();
var valueToSet = "<tag1>Value</tag1>";
//or var valueToSet = "Value";
//With XML tag:
if (valueToSet.Contains("</"))
{
var doc = new XmlDocument();
doc.LoadXml(valueToSet);
obj.Name.tag1 = doc.InnerText;
}
else //Without XML Tags
{
obj.Name.Value = senderRecipient.Name;
}
This solution will work in both cases, but has limitation. It will work only for predefined tags (ex. tag1)
My XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfAddressDetails xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AddressDetails>
<DbServerName>2k8</DbServerName>
</AddressDetails>
<AddressDetails>
<DbServerName>2k8R2D3</DbServerName>
</AddressDetails>
</ArrayOfAddressDetails>
And I created two classes for it as follows:
public class AddressDetails
{
public string DbServerName { get; set; }
}
}
and another class to hold a list of those:
public class AddressList
{
public List<AddressDetails> addressList= new List<AddressDetails>() ;
}
And this is how I am deserializng it:
XmlSerializer deSerializer = new XmlSerializer(typeof(AddressList));
TextReader reader = new StreamReader(#"C:\TEMP\MyXML.xml");
Object obj = deSerializer.Deserialize(reader);
AddressList adrsList = (AddressList)obj;
reader.Close();
But on Deserialize method I get this error:
You have to decorate:
AddressList class with XmlRoot attribute like this [XmlRoot("ArrayOfAddressDetails")]
addressList field with XmlElement attribute like this [XmlElement("AddressDetails")]
You have this at the end:
[XmlRoot("ArrayOfAddressDetails")]
public class AddressList
{
[XmlElement("AddressDetails")]
public List<AddressDetails> addressList = new List<AddressDetails>();
}
I have been trying to make an export/import program but when I try to import the XML-information to the textbox it doesn't work.
C# snippet from program:
XmlDocument doc = new XmlDocument();
doc.Load(open.FileName);
foreach (XmlNode x in doc.DocumentElement)
textBox6.Text = x["Contact"].Value;
and the XML-file is as follows:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<Table1>
<Contact>example</Contact>
</Table1>
</NewDataSet>
Original image:
http://i.stack.imgur.com/0ks2F.png
try use InnerText instead of value
textBox6.Text = x["Contact"].InnerText;
A breakpoint on the line
textBox6.Text = x["Contact"].Value;
should be revealing...
That's just based on visual inspection - people who supply XML as png files don't get it examined by me lol...
You can use XmlSerializer to achieve same operation.
Checkout following code.
using System.Xml.Serialization;
using System.IO;
namespace DemoApplication
{
class Program
{
static void Main(string[] args)
{
NewDataSet objNewDataSet = new NewDataSet();
Table objTable = new Table();
objTable.Conact = "Hello";
objNewDataSet.Table1 = objTable;
StreamWriter objStream = new StreamWriter("C:\\Users\\Nirav Kamani\\Desktop\\abc.xml");
XmlSerializer objXmlSerializer = new XmlSerializer(typeof(NewDataSet));
objXmlSerializer.Serialize(objStream, objNewDataSet);
}
}
}
Model Classes.
using System.Xml.Serialization;
namespace DemoApplication
{
public class NewDataSet
{
[XmlElement]
public Table Table1 { get; set; }
}
}
namespace DemoApplication
{
public class Table
{
public string Conact { get; set; }
}
}
You can serialize and deserialize easily.
For more information check out following links.
I am just giving you a better approach to achieve same operation in terms of objects.
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx