如何解析无效(坏/格式不正确)的XML?

2022-09-01 15:39:34

目前,我正在开发一项功能,该功能涉及解析我们从其他产品收到的XML。我决定对一些实际的客户数据运行一些测试,看起来其他产品允许用户输入应该被认为是无效的。无论如何,我仍然必须尝试找出一种方法来解析它。我们正在使用,但我在输入时收到一个错误,如下所示。javax.xml.parsers.DocumentBuilder

<xml>
  ...
  <description>Example:Description:<THIS-IS-PART-OF-DESCRIPTION></description>
  ...
</xml>

如您所知,描述内部似乎有一个无效的标签()。现在,已知此描述标记是叶标记,并且其中不应包含任何嵌套标记。无论如何,这仍然是一个问题,并产生一个例外<THIS-IS-PART-OF-DESCRIPTION>DocumentBuilder.parse(...)

我知道这是无效的XML,但它是可以预见的无效的。关于解析此类输入的方法的任何想法?


答案 1

“XML”比无效更糟糕 - 它不是格式正确的;请参阅格式良好与有效 XML

对违法行为的可预测性进行非正式评估无济于事。该文本数据不是 XML。任何符合标准的 XML 工具或库都无法帮助您处理它。

选项,最理想的第一:

  1. 让提供商在他们的一端解决问题。需要格式正确的 XML。(从技术上讲,短语格式正确的 XML 是多余的,但对于强调可能很有用。

  2. 使用容错的标记解析器在解析为 XML 之前清理问题:

  3. 使用文本编辑器手动将数据作为文本处理,或使用字符/字符串函数以编程方式处理数据。以编程方式执行此操作的范围从棘手到不可能,因为看似可预测的事情通常不是 - 违反规则很少受到规则的约束

    • 对于无效字符错误,请使用正则表达式删除/替换无效字符:

      • 菲律宾比索: preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $s);
      • 红宝石: 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, '')
    • 对于 & 符号,使用正则表达式将匹配项替换为:credit: blhsindemo&amp;

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

请注意,上述正则表达式不会考虑注释或 CDATA 部分。


答案 2

根据设计,标准 XML 解析器永远不会接受无效的 XML。

您唯一的选择是在解析输入之前,对输入进行预处理以删除“可预测的无效”内容,或将其包装在 CDATA 中。


推荐