Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams // Create an XmlReader using (XmlReader reader = XmlReader.Create(new StringReader(xoResponse.@return))) XmlWriterSettings ws = new XmlWriterSettings(); //ws.Indent = true; using (XmlWriter writer = XmlWriter.Create(output, ws)) // Parse the file and display each of the nodes. while (reader.Read()) switch (reader.NodeType) case XmlNodeType.Element: writer.WriteStartElement(reader.Name); break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.XmlDeclaration: case XmlNodeType.ProcessingInstruction: writer.WriteProcessingInstruction(reader.Name, reader.Value); break; case XmlNodeType.Comment: writer.WriteComment(reader.Value); break; case XmlNodeType.EndElement: writer.WriteFullEndElement(); break;

I believe that the error is thrown on the second parent element. How can I avoid this error? Any help is greatly appreciated.

Well, for a start, that stuff you're getting from the web service isn't XML, because it has two root elements, which is what's causing your problem. How are you getting it from the web service? Are you trimming the real root element off by accident somehow? Matt Gibson Feb 18, 2011 at 15:10 In that case, I'd mention to the service provider that it's no fun at all to have a document format that looks very much like XML but isn't actually XML :) I wonder if it's simply broken, or if there's some very odd reason they're doing that deliberately? Matt Gibson Feb 18, 2011 at 15:22 @Matt - good point, I'll bring it up to them. Maybe it was a test to rule out any unworthy web service users? :) divided Feb 18, 2011 at 15:26 It is "XML" but it isn't an XML document. You can still parse it, just need to relax the XmlReader. See my answer below. Mark Lakata Dec 10, 2012 at 21:03

You can do it without modifying the XML stream: Tell the XmlReader to not be so picky. Setting the XmlReaderSettings.ConformanceLevel to ConformanceLevel.Fragment will let the parser ignore the fact that there is no root node.

XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create(tr,settings))

Now you can parse something like this (which is an real time XML stream, where it is impossible to wrap with a node).

<event>
  <timeStamp>1354902435238</timeStamp>
  <eventId>7073822</eventId>
</event>
  <time>1354902435341</time>
  <payload type='80'>7d1300786a0000000bf9458b0518000000000000000000000000000000000c0c030306001b</payload>
</data>
  <time>1354902435345</time>
  <payload type='80'>fd1260780912ff3028fea5ffc0387d640fa550f40fbdf7afffe001fff8200fff00f0bf0e000042201421100224ff40312300111400004f000000e0c0fbd1e0000f10e0fccc2ff0000f0fe00f00f0eed00f11e10d010021420401</payload>
</data>
  <time>1354902435347</time>
  <payload type='80'>fd126078ad11fc4015fefdf5b042ff1010223500000000000000003007ff00f20e0f01000e0000dc0f01000f000000000000004f000000f104ff001000210f000013010000c6da000000680ffa807800200000000d00c0f0</payload>
</data>
                Abut the "it isn't an XML document"  claims: that's a matter of opinion and perspective. The input is a series of valid XML fragments. I used this answer.
– H H
                Apr 3, 2018 at 9:16
                This works. I had to parse .svclog files of several GB and wrapping the entire content with a root tag just to get proper "XML" is not an option.
– Wiizl
                Apr 23, 2020 at 12:44

You need to enclose your <parent> elements in a surrounding element as XML Documents can have only one root node:

<parents> <!-- I've added this tag -->
    <parent>
        <child>
        </child>
    </parent>
    <parent>
        <child>
            <grandchild>
            </grandchild>
            <grandchild>
            </grandchild>
        </child>
        <child>
        </child>
    </parent>
</parents> <!-- I've added this tag -->

As you're receiving this markup from somewhere else, rather than generating it yourself, you may have to do this yourself by treating the response as a string and wrapping it with appropriate tags, prior to attempting to parse it as XML.

So, you've a couple of choices:

  • Get the provider of the web service to return you actual XML that has one root node
  • Pre-process the XML, as I've suggested above, to add a root node
  • Pre-process the XML to split it into multiple chunks (i.e. one for each <parent> node) and process each as a distinct XML Document
  • @Rob what if there is a Doctype element on each parent element..Consider my case in my question stackoverflow.com/questions/7074036/… it is java not C# but I think logic is the same.. – Krishnabhadra Oct 5, 2011 at 9:41

    If you're in charge (or have any control over the web service), get them to add a unique root element!

    If you can't change that at all, then you can do a bit of regex or string-splitting to parse each and pass each element to your XML Reader.

    Alternatively, you could manually add a junk root element, by prefixing an opening tag and suffixing a closing tag.