B. Clay Shannon B. Clay Shannon -4 years ago 135
C# Question

How can I parse this XML (without getting "Root element is missing" or "Sequence contains no elements")?

This is an offshoot from this question Why is the HttpWebRequest body val null after "crossing the Rubicon"? which was answered (one hurdle is leapt), but the next hurdle trips me up.

With this code:

public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync());


...or this:

XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());


...and this as the incoming stringifiedXML:

<?xml version=1.0?>
<LocateAndLaunch>
<Tasks>Some Task</Tasks>
<Locations>Some Location</Locations>
</LocateAndLaunch>


...I get the exception: "System.Xml.XmlException was unhandled by user code HResult=-2146232000 Message=Root element is missing."

With this code (same stringifiedXML):

XDocument doc = XDocument.Parse(stringifiedXML);


... I get


System.InvalidOperationException was unhandled by user code
HResult=-2146233079 Message=Sequence contains no elements
Source=System.Core StackTrace: at
System.Linq.Enumerable.First[TSource](IEnumerable`1 source) at
HandheldServer.Controllers.DeliveryItemsController.d__2.MoveNext() in
c:\HandheldServer\HandheldServer
\Controllers\DeliveryItemsController.cs:line 109 InnerException:


IOW, depending on how I parse the incoming string, I get either "Root element is missing" or "Sequence contains no elements"

What the Deuce McAlistair MacLean Virginia Weeper?!? Isn't
<LocateAndLaunch>
a root element? Aren't
Some Task
and
Some Location
elements?

Will I need to manually take the XML apart without being able to use
XDocument
or such?

Note: From Fiddler, sending the body data (XML text) works (what I send arrives as I would hope); but even then, the XML parse code on the server fails.

Trying to send the same data from the handheld/Compact Framework client code, though, results in just the data through the "=" (something like
<xml version="
being passed to the server; and then on the client, I see "This operation cannot be performed after the request has been submitted"

UPDATE



So based on Marcin's answer, it seems if I stick with XDocument.Parse() I should be okay, and based on TToni's answer, the data/xml itself may be bad. Here is the contents of the file:

<?xml version="1.0"?>
<LocateAndLaunch>
<Tasks>
</Tasks>
<Locations>
</Locations>
</LocateAndLaunch>


So there are quotes around the version number - but do I need to escape these somehow - is this why the data is being truncated - because when it sees the first quote (before the "1.0") it thinks that is the string termination, maybe?

UPDATE 2



Marcin, the incoming "xml" data (string) is truncated before it ever gets to the XDocument code:

[Route("api/DeliveryItems/PostArgsAndXMLFileAsStr")]
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
string beginningInvoiceNum = string.Empty;
string endingInvoiceNum = string.Empty;

//XDocument doc = XDocument.Parse(stringifiedXML);
//XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync());
XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());


UPDATE 3



By using TToni's suggestion and replacing the double with single quotes:

...I'm now getting the whole string into my server method:

enter image description here

...but I'm still getting "Root element is missing":

System.Xml.XmlException was unhandled by user code
HResult=-2146232000
Message=Root element is missing.
Source=System.Xml
LineNumber=0
LinePosition=0
SourceUri=""
StackTrace:
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options)
at System.Xml.Linq.XDocument.Load(Stream stream)
at HandheldServer.Controllers.DeliveryItemsController.d__2.MoveNext() in c:\HandheldServer\HandheldServer\Controllers\DeliveryItemsController.cs:line 66
InnerException:


If I wasn't already crazy, this would drive me crazy. As it is, I don't know quite where I'm being driven. Many employers are looking for somebody who is driven; maybe this is what they mean?

UPDATE 4



Using this:

XDocument doc = XDocument.Parse(stringifiedXML);


...instead of this:

XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());


...solved the "Root element is missing" err msg; thus, I marked Marcin's answer as correct.

Answer Source

Sample XML you've provided works just fine with XDocument:

var stringifiedXML = @"<?xml version=""1.0""?>
    <LocateAndLaunch>
        <Tasks>Some Task</Tasks>
        <Locations>Some Location</Locations>
    </LocateAndLaunch>";

XDocument doc = XDocument.Parse(stringifiedXML);

var tasks = (string)doc.Root.Element("Tasks");
var locations = (string)doc.Root.Element("Locations");

So your problem is with await Request.Content.ReadAsStringAsync(), not with XDocument.

Make sure ReadAsStringAsync() returns what you need first.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download