Search code examples
c#jsonxmlbotframeworkchatbot

How to convert from xml to json within Adaptive dialog HttpRequest?


I am new to Bot Framework and C#. I am building a chatbot using Adaptive Dialog with the Core Flight Booking Template (adaptive-dialog/03.core-bot). I want to make an API call to get the weather information. This OpenWeather API can return data in JSON, XML, or HTML format. When the response is in JSON format, it is easy to access the key-value pairs. But when the response is in XML format, everything will be converted into a string and saved as 'content' in the response, I have to convert it into either JSON or a Dictionary so that I can access the detailed information. And I need to save the API response as a property in the dialog for later reference.

I know we can use the following code to convert from XML to JSON, but the question is how to do it in the adaptive dialog. I tried to include the following code in the HttpRequest block but got the error "XmlDocument is a type, which is not valid in the given context." It seems like you cannot add your own customized codes in the adaptive dialog, what you can do is only using what the template can offer, but right now the HttpRequest class does not have an option for parsing XML response. Can anyone please give me some guidance on this? Thanks!

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

string json = JsonConvert.SerializeXmlNode(doc);

Codes to make the HttpRequest in the adaptive dialog:

new IfCondition()
{
    Condition = "conversation.Id != null",
    Actions = new List<Dialog>()
    {
        new HttpRequest()
        {
            Url = "http://api.openweathermap.org/data/2.5/weatherq=Detroit&mode=xml&appid=appid={your api key}",
            ResultProperty = "dialog.httpResponse",
            Method = HttpRequest.HttpMethod.GET,
            ResponseType = HttpRequest.ResponseTypes.Json
        },
        new Send Activity("${dialog.httpResponse}"),
        new Send Activity("${dialog.httpResponse.content}")
    }
}

The following shows what the HttpRequest response looks like. The OpenWeather API response (XML format) is converted into a string as the value of 'content'.

{
    "statusCode": 200,
    "reasonPhrase": "OK",
    "headers": 
    {
        "Server": "openresty",
        "Date": "Tue, 14 Jul 2020 18:57:41 GMT",
        "Connection": "keep-alive",
        "X-Cache-Key": "/data/2.5/weather?mode=xml&q=detroit",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Allow-Methods": "GET, POST"
    },
    "content": "<?xml version="1.0" encoding="UTF-8"?>\n
                <current>
                    <city id="4990729" name="Detroit">
                        <coord lon="-83.05" lat="42.33"></coord> 
                        <country>US</country>
                        <timezone>-14400</timezone>
                        <sun rise="2020-07-14T10:08:16" set="2020-07-15T01:07:33"></sun>
                    </city>
                    <temperature value="301.11" min="300.15" max="302.59" unit="kelvin"></temperature>
                    <feels_like value="301.1" unit="kelvin"></feels_like> 
                    <humidity value="44" unit="%"></humidity>
                    <pressure value="1019" unit="hPa"></pressure>
                    <wind>
                        <speed value="2.1" unit="m/s" name="Light breeze"></speed>
                        <gusts></gusts>
                        <direction></direction>
                    </wind>
                    <clouds value="75" name="broken clouds"></clouds>
                    <visibility value="16093"></visibility>
                    <precipitation mode="no"></precipitation>
                    <weather number="803" value="broken clouds" icon="04d"></weather>
                    <lastupdate value="2020-07-14T18:57:41"></lastupdate> 
               </current>"
}

Solution

  • You can use a code action.

    new IfCondition()
    {
        Condition = "conversation.Id != null",
        Actions = new List<Dialog>()
        {
            new HttpRequest()
            {
                Url = "http://api.openweathermap.org/data/2.5/weatherq=Detroit&mode=xml&appid=appid={your api key}",
                ResultProperty = "dialog.httpResponse",
                Method = HttpRequest.HttpMethod.GET,
                ResponseType = HttpRequest.ResponseTypes.Json
            },
            new CodeAction(async (dc, options) =>
            {
                var xml = dc.State.GetValue("dialog.httpResponse.content", () => "<root></root>");
                var doc = new XmlDocument();
    
                doc.LoadXml(xml);
    
                var json = JsonConvert.SerializeXmlNode(doc);
    
                dc.State.SetValue("dialog.json", json);
    
                return await dc.EndDialogAsync();
            }),
            new SendActivity("${dialog.json}"),
        }
    }