0

I have a WPF application that calls an API and creates an System.Xml.Linq.XDocument using XDocument.Parse(string). I am running into a problem where an XmlException ("Root element is missing") is thrown when I try to do this, but my XML is completely valid. I tried syntax-checking it by calling the API in my browser and checking its syntax, calling the API in my application and Console.WriteLineing the response, and using various XML syntax validators (all of which returned no errors).
A sample XML response from the API is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <event title="Event 1" id="75823347" icon="www.example.com/images/event1-icon.png" uri="www.example.com/rsvp/event1" mode="none" price="10.00" cover="www.example.com/event1-cover.png" enddate="2016-06-01 14:00:00" startdate="2016-06-01 12:00:00" address="1 Example St, Example City State 12345" location="Example Place" description="This is an event" shortdescription="This is an event" theme="auto" color="#FF000000"/>
</response>

This is my application's code:

public static WebRequest CreateRequest(string baseUrl, string httpMethod, Dictionary<string, string> requestValues) {
    var requestItems = requestValues == null ? null : requestValues.Select(pair => string.Format("&{0}={1}", pair.Key, pair.Value));
    var requestString = "";
    if (requestItems != null)
        foreach (var s in requestItems)
            requestString += s;
    var request = WebRequest.CreateHttp(baseUrl + CredentialRequestString + requestString);
    request.Method = httpMethod.ToUpper();
    request.ContentType = "application/x-www-form-urlencoded";
    request.Credentials = CredentialCache.DefaultCredentials;
    return request;
}

public static WebRequest CreateRequest(string apiEndpoint, string endpointParam, int apiVersion, string httpMethod, Dictionary<string, string> requestValues) {
    return CreateRequest(string.Format("http://www.example.com/api/v{0}/{1}/{2}", apiVersion, apiEndpoint, endpointParam), httpMethod, requestValues);
}

public static async Task<string> GetResponseFromServer(WebRequest request) {
    string s;
    using (var response = await request.GetResponseAsync()) {
        using (var responseStream = response.GetResponseStream()) {
            using (var streamReader = new StreamReader(responseStream)) {
                s = streamReader.ReadToEnd();
            }
        }
    }
    return s;
}

public static async Task<List<Event>> GetEvents() {
    var response = await GetResponseFromServer(CreateRequest("events", "", 1, "GET", null));
    Console.WriteLine(response); //validation
    var data = XDocument.Parse(response).Root; //XmlException: Root element is mising
    return new List<Event>(data.Elements("event").Select(e => Event.FromXml(e.Value)));
}

Why is this happening?

Greg Whatley
  • 1,020
  • 1
  • 13
  • 32
  • If the xml were valid it would not throw that exception. How are you doing the "syntax-checking"? – Crowcoder May 30 '16 at 15:03
  • @Crowcoder I carefully check the formatting to ensure that all tags are closed, all quotes are closed, and there are no reserved characters being used. I also used [W3School's XML Validator](http://www.w3schools.com/xml/xml_validator.asp). – Greg Whatley May 30 '16 at 15:35
  • Usually this errror occurs when " – jdweng May 30 '16 at 15:36

1 Answers1

1

The following code works

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            var data = XDocument.Load(FILENAME); 
            Event _event = Event.FromXml(data.Descendants("event").FirstOrDefault());
        }
    }
    public class Event
    {
        public string title { get ; set; }
        public string icon  {get; set; }
        public string uri  { get; set; }
        public string mode { get;set; }
        public decimal price { get; set; }
        public string cover { get; set; }
        public DateTime enddate { get; set; }
        public DateTime startdate { get; set; }
        public string address { get; set; }
        public string location { get; set; }
        public string description { get; set; }
        public string shortdescription { get; set; }
        public string theme { get; set; }
        public uint color { get; set; }


        public static Event FromXml(XElement data)
        {
            Event _event = new Event();

            _event.title = (string)data.Attribute("title");
            _event.icon = (string)data.Attribute("icon");
            _event.uri = (string)data.Attribute("uri");
            _event.mode = (string)data.Attribute("mode");
            _event.price = (decimal)data.Attribute("price");
            _event.cover = (string)data.Attribute("cover");
            _event.enddate = (DateTime)data.Attribute("enddate");
            _event.startdate = (DateTime)data.Attribute("startdate");
            _event.address = (string)data.Attribute("address");
            _event.location = (string)data.Attribute("location");
            _event.description = (string)data.Attribute("description");
            _event.shortdescription = (string)data.Attribute("shortdescription");
            _event.theme = (string)data.Attribute("theme");
            _event.color = uint.Parse(data.Attribute("color").Value.Substring(1), System.Globalization.NumberStyles.HexNumber) ;

            return _event;
        }

    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • I'm accepting this as the solution because my own implementation of `FromXml` was very strange and somewhat stupid on my part. I rewrote it to work similar to yours and now everything is working fine. – Greg Whatley May 30 '16 at 18:41
  • You first error was due to using 'Root' in your linq query which removed the identification line from the xml. I quickly noticed that error but your xml linq query did not look correct so I decided to fix both issues. – jdweng May 30 '16 at 23:47