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

Java 如何解析无效(错误/格式不正确)的XML?,java,xml,xml-parsing,xml-validation,Java,Xml,Xml Parsing,Xml Validation,目前,我正在开发一个功能,它涉及解析我们从另一个产品收到的XML。我决定对一些实际的客户数据运行一些测试,而另一个产品似乎允许用户输入应该被视为无效的数据。不管怎么说,我还是要想办法解析它。我们使用的是javax.xml.parsers.DocumentBuilder,输入时出现如下错误 <xml> ... <description>Example:Description:<THIS-IS-PART-OF-DESCRIPTION></descri

目前,我正在开发一个功能,它涉及解析我们从另一个产品收到的XML。我决定对一些实际的客户数据运行一些测试,而另一个产品似乎允许用户输入应该被视为无效的数据。不管怎么说,我还是要想办法解析它。我们使用的是
javax.xml.parsers.DocumentBuilder
,输入时出现如下错误

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

...
示例:说明:
...
正如您所知,描述中似乎有一个无效的标记(
)。现在,这个描述标签是一个叶子标签,里面不应该有任何嵌套的标签。无论如何,这仍然是一个问题,并在
DocumentBuilder.parse(…)


我知道这是无效的XML,但可以预见它是无效的。关于解析这种输入的方法有什么想法吗?

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


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

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

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

认为“XML”比无效更糟糕——它的格式不好;请参见

对违法行为的可预测性进行非正式评估无济于事。该文本数据不是XML。没有一致的XML工具或库可以帮助您处理它

选项,首先是最理想的:
  • 让提供商解决他们端的问题要求格式良好的XML。(从技术上讲,格式良好的XML是多余的,但可能有助于强调。)

  • 在解析为XML之前,请使用容错标记解析器清除问题:

    • 单机版:具有强大的恢复和修复功能信贷:

    • 单机版和C/C++:也适用于XML。是TangSuffic到C++的端口。
    • Python:是基于Python的。请参见本节中的注释。有关更多信息,请参见 处理Python中格式不正确的标记的建议, 尤其包括。 有关如何使用
      codecs.EncodedFile()
      清除非法字符,请参见

    • Java:并关注HTML。可用于

    • .NET:

      • 能 被禁用以克服非法XML字符问题
      • 可以设置为 这样就可以读取缺少根元素的内容
      • 有时也会这样 习惯,但注意 下面第3条中的违规警告
      • 被称为“容错”
    • PHP:请参阅和。看一个很好的例子

    • Ruby:Nokogiri支持“”

    • R:有关R中的容错标记解析,请参阅

    • Perl:请参阅“一个超级自由的XML解析器,可以解析破碎的XML。”

  • 使用文本编辑器或 以编程方式使用字符/字符串函数。这样做 从编程角度来看,可以是棘手的,也可以是不可能的 看起来是什么 可预测性通常是不可预测的--违反规则很少受规则约束

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

      • preg\u 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},'')
      • inputStr.replace(/[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm',)
    • 对于符号,使用正则表达式将匹配项替换为
      :credit:

  • 请注意,上面的正则表达式不接受注释或CDATA 考虑到部分。

    认为“XML”比无效更糟糕–它的格式不正确;请参见

    对违规行为的可预测性进行非正式评估并没有帮助。文本数据不是XML。并没有一致的XML工具或库可以帮助您处理它

    选项,首先是最理想的:
  • 让提供商解决问题。要求格式良好的XML。(从技术上讲,格式良好的XML是多余的,但可能有助于强调。)

  • 在解析为XML之前,请使用容错标记解析器清除问题:

    • 单机版:具有强大的恢复和修复功能信贷:

    • <> >强>独立和C/C++:与XML也是工作的。C++是TangToice的一个端口。
    • Python:是基于Python的。请参阅本节中的注释。有关更多信息,请参阅 处理Python中格式不正确的标记的建议, 尤其包括。 有关如何使用
      codecs.EncodedFile()
      清除非法字符,请参见

    • Java:并关注HTML。可用于

    • .NET:

      • 能 被禁用以克服非法XML字符问题
      • 可以设置为 这样就可以读取缺少根元素的内容
      • 有时也会这样 习惯,但注意 下面第3条中的违规警告
      • 被称为“容错”
    • PHP:请参阅和。请参阅好的示例

    • Ruby:Nokogiri支持“”

    • R:有关R中的容错标记解析,请参阅

    • Perl:xmlstarlet fo -o -R -H -D bad.xml 2>/dev/null
      &(?!(?:#\d+|#x[0-9a-f]+|\w+);)
      
      <root>
           <element>...</element>
           <element>...</element>
      </root>
      
      <element>...</element>
      <element>...</element>
      <element>...</element>
      <element>...</element>
      
      File file = new File(pathtofile);
      
      FileInputStream fis = new FileInputStream(file);
      
      List<InputStream> streams = 
          Arrays.asList(
              new ByteArrayInputStream("<root>".getBytes()),
          fis,
          new ByteArrayInputStream("</root>".getBytes()));
      
      InputStream cntr = 
      new SequenceInputStream(Collections.enumeration(str));
      
      <!DOCTYPE xml [
        <!ELEMENT xml - - ANY>
        <!ELEMENT description - - ANY>
        <!ELEMENT THIS-IS-PART-OF-DESCRIPTION -  - EMPTY>
      ]>
      <xml>
        <description>blah blah
          <THIS-IS-PART-OF-DESCRIPTION>
        </description>
      </xml>