Common causes
1. Several records without a common parent
Exports and logs that write one element per record produce a list of roots. Wrap them in a container element.
<user id="1"/>
<user id="2"/><users>
<user id="1"/>
<user id="2"/>
</users>2. Documents concatenated with their declarations
Appending one XML file to another repeats the <?xml ?> declaration and the root. Merge the content under one root and keep a single declaration at the top.
<?xml version="1.0"?>
<feed><entry>A</entry></feed>
<?xml version="1.0"?>
<feed><entry>B</entry></feed><?xml version="1.0"?>
<feed>
<entry>A</entry>
<entry>B</entry>
</feed>3. Text or a stray closing tag after the root
A debug line, a status word or an extra </root> printed after the document counts as junk. Make sure the writer emits nothing after the final end tag.
<status code="200"/>
OK<status code="200">OK</status>Frequently asked questions
Why does Python say "column 0"?
Expat counts columns from 0, so column 0 is the first character of the line. Other tools, including PasteKit, count from 1.
Are comments allowed after the root element?
Yes. Comments, processing instructions and whitespace may appear after the root. Elements and non-whitespace text may not.
How do I process a file that contains many XML documents?
Split it at the declarations or root elements and parse each piece separately, or wrap the whole stream in a synthetic root element before parsing.