目前,我正在开发一项功能,该功能涉及解析从另一产品收到的XML。我决定对一些实际的客户数据进行一些测试,看起来其他产品正在允许来自用户的输入被认为是无效的。无论如何,我仍然必须尝试找出一种解析它的方法。我们正在使用javax.xml.parsers.DocumentBuilder,但输入出现错误,如下所示。
javax.xml.parsers.DocumentBuilder
<xml> ... <description>Example:Description:<THIS-IS-PART-OF-DESCRIPTION></description> ... </xml>
如你所知,说明中包含(<THIS-IS-PART-OF-DESCRIPTION>)似乎是无效标签的内容。现在,此描述标签被称为是叶子标签,并且其中不应包含任何嵌套标签。无论如何,这仍然是一个问题,并且会在DocumentBuilder.parse(...)
(<THIS-IS-PART-OF-DESCRIPTION>)
DocumentBuilder.parse(...)
我知道这是无效的XML,但是可以预期它是无效的。关于解析此类输入的方法有什么想法吗?
“ XML”比无效更糟糕–它的格式不正确;请参阅格式正确与有效XML。
对违法行为的可预测性进行非正式评估无济于事。该文本数据不是XML。没有一致的XML工具或库可以帮助你处理它。
选项,最可取的是:
使用容忍标记解析器在解析为XML之前清除问题:
Standalone: xmlstarlet具有强大的恢复和修复功能信誉:RomanPerekhrest
xmlstarlet fo -o -R -H -D bad.xml 2>/dev/null
**Standalone andC / C **: HTML Tidy也可以与XML一起使用。 Taggle是TagSoup到C 的移植。
Python: Beautiful Soup是基于Python的。请参阅解析器之间的差异部分中的注释。另请参阅此问题的答案,以获取更多有关处理Python中格式错误的标记的建议。另请参阅此答案以了解如何codecs.EncodedFile()用于清除非法字符。
Beautiful Soup
Python
codecs.EncodedFile()
TagSoup
JSoup
HTML
FilterInputStream
XmlReaderSettings.CheckCharacters
@jdweng还报告说XmlReader.ReadToFollowing()
Microsoft.Language.Xml.XMLParser
DOMDocument :: $ recover
libxml_use_internal_errors(true)
Nokogiri
“ Gentle Well-Formedness ”
htmlTreeParse()
Perl:请参阅XML :: Liberal,这是“超级自由的XML解析器,用于解析损坏的XML”。
Liberal
使用文本编辑器手动将数据处理为文本,或使用字符/字符串功能以编程方式处理数据。以编程方式执行此操作的范围可能从棘手到不可能,因为似乎经常可以预测的事情并非如此- 打破规则很少受规则约束。
对于无效字符错误,请使用regex删除/替换无效字符:
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, '')
JavaScript
inputStr.replace(/[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm, '')
对于&符,请使用正则表达式将匹配项替换为&:credit:blhsin,demo
&
&(?!(?:#\d+|#x[0-9a-f]+|\w+);)
请注意,上面的正则表达式不会考虑注释或CDATA部分。