Search code examples
c#asp.net-coretally

How to get rid of () special character in Tally XML Ledger Export Response


I am getting the following error while deserializing the xml response from ledger export request in tally in C#.

Error "XmlException: '', hexadecimal value 0x04, is an invalid character. " This is due to (&#4) character in front of Primary in Parent element.

<LEDGER>
 <NAME>Profit &amp; Loss A/c</NAME>
 <PARENT>&#4; Primary</PARENT>
 <OPENINGBALANCE>1000.00</OPENINGBALANCE>
 <CLOSINGBALANCE>2000.00</CLOSINGBALANCE>
</LEDGER>

Anyone knows, either how to get rid of this character in the response or ignore while deserializing?

Thank you.

C# Code

[XmlRoot(ElementName = "LEDGER")]
public class Ledger
{
    [XmlElement(ElementName = "NAME")]
    public string Name { get; set; } = string.Empty;
    [XmlElement(ElementName = "PARENT")]
    public string Parent { get; set; } = string.Empty;
    [XmlElement(ElementName = "OPENINGBALANCE")]
    public string OpeningBalance { get; set; } = string.Empty;
    [XmlElement(ElementName = "CLOSINGBALANCE")]
    public string ClosingBalance { get; set; } = string.Empty;
}
[XmlRoot(ElementName = "LEDGERS")]
public class Ledgers
{
    [XmlElement(ElementName = "LEDGER")]
    public List<Ledger> Ledgers { get; set; } = new List<Ledger>();
}
var content = new StringContent("<ENVELOPE><HEADER><VERSION>1</VERSION><TALLYREQUEST>EXPORT</TALLYREQUEST><TYPE>DATA</TYPE><ID>CA_LEDGER</ID></HEADER><BODY><DESC><STATICVARIABLES><SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT><SVCURRENTCOMPANY>Demo-Company</SVCURRENTCOMPANY></STATICVARIABLES><TDL><TDLMESSAGE><REPORT ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\"ISINTERNAL=\"NO\" NAME=\"CA_LEDGER\"><FORM>CA_LEDGER</FORM></REPORT><FORM ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\" ISINTERNAL=\"NO\"NAME=\"CA_LEDGER\"><PART>CA_LEDGER</PART><XMLTAG>LEDGERS</XMLTAG></FORM><PART ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\" ISINTERNAL=\"NO\"NAME=\"CA_LEDGER\"><LINE>CA_LEDGER</LINE><REPEAT>CA_LEDGER:CA_LEDGERCOLLECTION</REPEAT><SCROLLED>Vertical</SCROLLED></PART><LINE ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\" ISINTERNAL=\"NO\"NAME=\"CA_LEDGER\"><FIELDS>CA_NAME,CA_PARENT,CA_OPENINGBALANCE,CA_CLOSINGBALANCE</FIELDS><XMLTAG>LEDGER</XMLTAG></LINE><FIELD ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\"ISINTERNAL=\"NO\" NAME=\"CA_NAME\"><SET>$NAME</SET><XMLTAG>NAME</XMLTAG></FIELD><FIELD ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\"ISINTERNAL=\"NO\" NAME=\"CA_PARENT\"><SET>$PARENT</SET><XMLTAG>PARENT</XMLTAG></FIELD><FIELD ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\"ISINTERNAL=\"NO\" NAME=\"CA_OPENINGBALANCE\"><TYPE>Amount</TYPE><SET>$OPENINGBALANCE</SET><XMLTAG>OPENINGBALANCE</XMLTAG></FIELD><FIELD ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\"ISINTERNAL=\"NO\" NAME=\"CA_CLOSINGBALANCE\"><TYPE>Amount</TYPE><SET>$CLOSINGBALANCE</SET><XMLTAG>CLOSINGBALANCE</XMLTAG></FIELD><COLLECTION ISMODIFY=\"NO\" ISFIXED=\"NO\" ISINITIALIZE=\"NO\" ISOPTION=\"NO\"ISINTERNAL=\"NO\" NAME=\"CA_LEDGERCOLLECTION\"><TYPE>Ledger</TYPE><NATIVEMETHOD>Name</NATIVEMETHOD><NATIVEMETHOD>Parent</NATIVEMETHOD><NATIVEMETHOD>OpeningBalance</NATIVEMETHOD><NATIVEMETHOD>ClosingBalance</NATIVEMETHOD></COLLECTION></TDLMESSAGE></TDL></DESC></BODY></ENVELOPE>", null, "application/xml");
var response = await new HttpClient().PostAsync(URL, content); // Url is http://localhost:1000
if (!response.IsSuccessStatusCode)
{
    return Enumerable.Empty<Ledger>();
}
XmlSerializer serializer = new XmlSerializer(typeof(Ledgers));
var ledgers = (Ledgers?)serializer.Deserialize(await response.Content.ReadAsStreamAsync());

Solution

  • there is no way you can restrict that from Tally

    But you can just do var xml = xml .Replace("&#4; ", "")

    Since you are using C# you can use TallyConnector Library created by me which is open-source and available as nugget

    To get ledgers using TallyConnector you can simply call

        var TC = new TallyService();
        List<Ledger> Ledgers = await TC .GetLedgersAsync();
    

    All these common problems like Replacing '&#4' also handled by library.