Home > Blockchain >  XML Parsing with C# from a service
XML Parsing with C# from a service

Time:06-19

I am having a bad time trying to consume an XML service.

This is my code to consume the service (it is a public service so you can consume it):

using( var client = new HttpClient() )
{
    client.DefaultRequestHeaders
        .Accept
        .Add( new MediaTypeWithQualityHeaderValue( "text/xml" ) );
    var request = new HttpRequestMessage( HttpMethod.Get, "https://gee.bccr.fi.cr/Indicadores/Suscripciones/WS/wsindicadoreseconomicos.asmx/ObtenerIndicadoresEconomicosXML?Indicador=317&FechaInicio=20/04/2022&FechaFinal=20/04/2022&Nombre=José Miguel Torres Gómez&SubNiveles=N&[email protected]&Token=2LOEU2EM8O" );
    var returnedXml = client.SendAsync( request ).Result.Content.ReadAsStringAsync().Result;

    Console.WriteLine( returnedXml );
}

The response I get from there is the following, adding the console screenshot due to it returns special scape chars: enter image description here

<string xmlns="http://ws.sdde.bccr.fi.cr">
  <Datos_de_INGC011_CAT_INDICADORECONOMIC>
    <INGC011_CAT_INDICADORECONOMIC>
      <COD_INDICADORINTERNO>317</COD_INDICADORINTERNO>
      <DES_FECHA>2022-04-20T00:00:00-06:00</DES_FECHA>
      <NUM_VALOR>650.10000000</NUM_VALOR>
    </INGC011_CAT_INDICADORECONOMIC>
  </Datos_de_INGC011_CAT_INDICADORECONOMIC>
</string>

This is the class I use to try to deserialize:

public class Datos_de_INGC011_CAT_INDICADORECONOMIC
{
    public INGC011_CAT_INDICADORECONOMIC INGC011_CAT_INDICADORECONOMIC { get; set; }
}
public class INGC011_CAT_INDICADORECONOMIC
{
    public int COD_INDICADORINTERNO { get; set; }
    public DateTime DES_FECHA { get; set; }
    public double NUM_VALOR { get; set; }
}

But when I try to Deserialize the string I get the error: There is an error in XML document. Data at the root level is invalid. And due to I don't use to work with XML data I am stocked here.

CodePudding user response:

Looks like the problem you are having is because of the outer element you have in your xml (string)

You can use one of the ways mentioned enter image description here

CodePudding user response:

The problem is that the "outer" XML is a wrapper for the "inner" one, which is encoded as text node for the first. In other words, that's NOT a single document, rather two different documents nested.

My guess is about the outer one, which looks like a descriptor for what itself contains.

That being said, you can extract what you need in a two-step job:

using System;
using System.Xml.Linq;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

using( var client = new HttpClient() )
{
    client.DefaultRequestHeaders
        .Accept
        .Add( new MediaTypeWithQualityHeaderValue( "text/xml" ) );
    var request = new HttpRequestMessage( HttpMethod.Get, " ... " );
    var returnedXml = client.SendAsync( request ).Result.Content.ReadAsStringAsync().Result;

    Console.WriteLine( returnedXml );

    //create a XML DOM from the returned payload
    XDocument xdoc_outer = XDocument.Parse(returnedXml );

    //extract the inner document as text (being a true-text node)
    string inner_text = (string)xdoc_outer.Root;

    //deserialize the text straight to a POCO shaped accordingly
    var serializer = new XmlSerializer(typeof(Datos_de_INGC011_CAT_INDICADORECONOMIC));
    using (var reader = XmlReader.Create(new StringReader(inner_text)))
    {
        //'result' contains the deserialized POCO, unless something went wrong!
        var result = (Datos_de_INGC011_CAT_INDICADORECONOMIC)serializer.Deserialize(reader);
        
    }
}

Probably there are better yet compact ways to achieve the same result, but I think that's pretty clear.

As final note, I reccomend to use async/await than accessing the data through the Result property.

  • Related