A parser message like Extra content at the end of the document tells you exactly what is wrong, once you know how it words things. Below are five errors that account for most broken XML I see, the message a parser prints for each, and the fix. The messages come from libxml2 (the parser behind PHP's DOMDocument, xmllint and many other tools); other parsers word them differently but point at the same problems.
1. Mismatched closing tag
<item><name>A</item>
libxml2 says: Opening and ending tag mismatch: name line 1 and item.
The parser found </item> while <name> was still open. Close the innermost element first:
<item><name>A</name></item>
2. An unescaped ampersand
<name>R&D</name>
libxml2 says: EntityRef: expecting ';'.
In XML, & starts an entity reference such as &. A bare ampersand in text is an error, which is why URLs with query strings break feeds. Escape it:
<name>R&D</name>
3. Two root elements
<a/><b/>
libxml2 says: Extra content at the end of the document.
A document has exactly one root element. Wrap the siblings:
<root><a/><b/></root>
4. A missing closing quote in an attribute
<item id="42></item>
libxml2 says: Unescaped '<' not allowed in attributes values.
The message is confusing: the parser kept reading the attribute value past 42> until it hit the next <. The real mistake is the missing quote:
<item id="42"></item>
Rule of thumb: when the message points at an attribute, check the quote before it.
5. ]]> inside a CDATA section
<s><![CDATA[a ]]> b]]></s>
libxml2 says: Sequence ']]>' not allowed in content.
The sequence ]]> ends a CDATA section, so it cannot appear inside one. Split it across two sections:
<s><![CDATA[a ]]]]><![CDATA[> b]]></s>
The text content of that element is still a ]]> b.
A note on namespaces
<media:title>Demo</media:title>
xmllint prints namespace error : Namespace prefix media on title is not defined, yet some libraries, including PHP's DOMDocument::loadXML, still load the document and only record the problem. If a feed works in one tool and fails in another, an undeclared prefix is a likely reason. Declare it on the root: <root xmlns:media="urn:media">.
Fix fast
Fix the first error only, then re-run: one early mistake (a missing quote, an unclosed tag) often produces several later messages. To paste a document and see the line and column, I use an XML validator, then an XML formatter to indent the result. The longer reference, with namespaces, CDATA and XPath, is in the XML guide.
Top comments (0)