如何parsing无效的(坏的/不正确的)XML?
目前,我正在研究一个涉及parsing从其他产品收到的XML的function。 我决定对一些实际的客户数据进行一些testing,看起来另一种产品允许来自用户的input被认为是无效的。 无论如何,我仍然需要尝试找出一种parsing方法。 我们正在使用javax.xml.parsers.DocumentBuilder
而且input错误如下所示。
<xml> ... <description>Example:Description:<THIS-IS-PART-OF-DESCRIPTION></description> ... </xml>
正如你所看到的,描述里面有一个无效的标签( <THIS-IS-PART-OF-DESCRIPTION>
)。 现在,这个描述标签被认为是一个叶子标签,它不应该有任何嵌套的标签。 无论如何,这仍然是一个问题,并产生DocumentBuilder.parse(...)
我知道这是无效的XML,但它是可以预见的无效。 任何想法的方式来parsing这样的input?
这个“XML”比无效的更糟 – 它不是完整的 ; 看看格式良好与有效的XML 。
对违规的可预见性进行非正式评估并没有帮助。 该文本数据不是XML。 没有一致的XML工具或库可以帮助您处理它。
选项,以降低满意度的顺序:
- 让提供者解决他们的问题。 要求格式良好的XML。 (从技术上讲, 格式良好的XML是多余的,但对强调可能有用。)
-
使用宽容的标记parsing器来清理parsing之前的XML问题:
-
独立: xmlstarlet具有强大的恢复和修复function信用: RomanPerekhrest
xmlstarlet fo -o -R -H -D bad.xml 2>/dev/null
-
独立和C: HTML Tidy也适用于XML。
- Python: 美丽的汤是基于Python的。 请参阅“ parsing器之间的差异”部分中的说明。 有关在Python中处理非格式标记的更多build议,另请参阅此问题的答案 。 另请参阅此答案以了解如何使用
codecs.EncodedFile()
清除非法字符。 - Java: JSoup专注于HTML。
FilterInputStream
可以用于预处理清理 。 -
。净:
-
可以禁用XmlReaderSettings.CheckCharacters以避开非法的XML字符问题。
-
@jdweng报告说有时可以使用
XmlReader.ReadToFollowing()
来解决XML语法问题 ,但是请注意下面#3中的违反规则的警告。 - 据说
Microsoft.Language.Xml.XMLParser
是“容错”的。
-
- PHP:请参阅DOMDocument :: $ recover和libxml_use_internal_errors(true) 。 看到很好的例子。
- R:请参阅htmlTreeParse(),了解R中的容错标记分析。
-
-
手动使用文本编辑器或使用字符/string函数以编程方式将数据处理为文本 。 以程序化的方式执行此操作的范围可以从棘手到不可能,因为似乎常常是可预测的不是 – 规则中断很less受规则约束 。
- 对于无效字符错误 ,请使用正则expression式来删除/replace无效字符:
- 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, '')
- PHP:
- 对于无效字符错误 ,请使用正则expression式来删除/replace无效字符:
一个标准的XMLparsing器将永远不会接受无效的XML,通过devise。
您唯一的select是预处理input以删除“可预测的无效”内容,或者在parsing之前将其包装在CDATA中。