How to parse invalid (bad / not well-formed) XML? How to parse invalid (bad / not well-formed) XML? xml xml

How to parse invalid (bad / not well-formed) XML?


That "XML" is worse than invalid – it's not well-formed; see Well Formed vs Valid XML.

An informal assessment of the predictability of the transgressions does not help. That textual data is not XML. No conformant XML tools or libraries can help you process it.

Options, most desirable first:

  1. Have the provider fix the problem on their end. Demand well-formed XML. (Technically the phrase well-formed XML is redundant but may be useful for emphasis.)

  2. Use a tolerant markup parser to cleanup the problem ahead of parsing as XML:

  3. Process the data as text manually using a text editor orprogrammatically using character/string functions. Doing thisprogrammatically can range from tricky to impossible aswhat appears to bepredictable often is not -- rule breaking is rarely bound by rules.

    • For invalid character errors, use regex to remove/replace invalid characters:

      • PHP: preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $s);
      • Ruby: string.tr("^\u{0009}\u{000a}\u{000d}\u{0020}-\u{D7FF}\u{E000‌​}-\u{FFFD}", ' ')
      • JavaScript: inputStr.replace(/[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm, '')
    • For ampersands, use regex to replace matches with &: credit: blhsin, demo

      &(?!(?:#\d+|#x[0-9a-f]+|\w+);)

Note that the above regular expressions won't take comments or CDATAsections into account.


A standard XML parser will NEVER accept invalid XML, by design.

Your only option is to pre-process the input to remove the "predictably invalid" content, or wrap it in CDATA, prior to parsing it.


IMO these cases should be solved by using JSoup.

Below is a not-really answer for this specific case, but found this on the web (thanks to inuyasha82 on Coderwall). This code bit did inspire me for another similar problem while dealing with malformed XMLs, so I share it here.

Please do not edit what is below, as it is as it on the original website.

The XML format, requires to be valid a unique root element declared in the document. So for example a valid xml is:

<root>     <element>...</element>     <element>...</element></root>

But if you have a document like:

<element>...</element><element>...</element><element>...</element><element>...</element>

This will be considered a malformed XML, so many xml parsers just throw an Exception complaining about no root element. Etc.

In this example there is a solution on how to solve that problem and succesfully parse the malformed xml above.

Basically what we will do is to add programmatically a root element.

So first of all you have to open the resource that contains your "malformed" xml (i. e. a file):

File file = new File(pathtofile);

Then open a FileInputStream:

FileInputStream fis = new FileInputStream(file);

If we try to parse this stream with any XML library at that point we will raise the malformed document Exception.

Now we create a list of InputStream objects with three lements:

A ByteIputStream element that contains the string: ""Our FileInputStreamA ByteInputStream with the string: ""So the code is:

List<InputStream> streams =     Arrays.asList(        new ByteArrayInputStream("<root>".getBytes()),    fis,    new ByteArrayInputStream("</root>".getBytes()));

Now using a SequenceInputStream, we create a container for the List created above:

InputStream cntr = new SequenceInputStream(Collections.enumeration(str));

Now we can use any XML Parser library, on the cntr, and it will be parsed without any problem. (Checked with Stax library);