【问题标题】:Replacing characters in a non well-formed XML body替换格式不正确的 XML 正文中的字符
【发布时间】:2011-03-01 19:38:18
【问题描述】:

在我正在处理的(Java)代码中,我有时会处理格式不正确的 XML(表示为 Java String),例如:

<root>
  <foo>
    bar & baz < quux
  </foo>
</root>

由于这个 XML 最终需要被解组(使用 JAXB),显然这个 XML 会在解组时抛出异常。

&amp;&amp;lt; 替换为其字符实体的最佳方法是什么?对于&amp;,很简单:

xml.replaceAll("&", "&amp;")

但是,对于 &amp;lt; 符号,这有点棘手,因为显然我不想替换用于 XML 标记开头“括号”的 &amp;lt;

除了扫描字符串并手动将 XML 正文中的 &amp;lt; 替换为 &amp;lt; 之外,您还有什么建议?

【问题讨论】:

  • 您的程序将如何区分文本中的 (位于 foo 元素内)和 XML 中的 (以 foo 元素结尾)?
  • 如何判断&amp;lt; 是否是打开标签?
  • 每个标签和值是否像您的示例一样打印在一行上?
  • @Sjoerd:就本应用而言,可以安全地假设正文中没有“XML 结束标记”,即正文中没有&lt;/foo&gt;跨度>
  • @stacker: 不,整个 XML 可以在 1 行中。

标签: java xml non-well-formed


【解决方案1】:

坦率地说,修复格式错误的 XML 的最佳方法是将其发回给生成它的人,并要求他们向您发送格式正确的 XML。您展示了一个简单的示例,它可能有解决方案,但修复格式错误的 XML 的通用方法将是一项可怕的工作。

而且由于不需要 XML 解析器来处理格式错误的 XML,因此您的解析器也不需要这样做。只是不要这样做。

【讨论】:

    【解决方案2】:

    我猜你需要更高级的逻辑。最好先使用“(]+>)”之类的正则表达式定位所有真实标签,然后只替换那些匹配项之外的文本,但显然你将无法使用 replaceAll 方法。这将更像是一项管道工作......

    【讨论】:

      【解决方案3】:

      虽然它是一个旧帖子,但我认为它可能对其他人有所帮助..我有相同的要求/问题,我可以使用以下代码解决。

      import java.util.regex.Matcher;
      import java.util.regex.Pattern;
      
      
      public class XMLTest {
      
      /**
      * @param args
      */
      
      public static void main(String[] args) {
      
      String xml = "<xml><body>" +
      "<message>something < between <<<  somthing </message>" +
      "<text> testing  >> > testing </text>" +
      "</body></xml>";
      
      Pattern replaceGTPattern = Pattern.compile(">[^<](.[^<]*)(>)+");
      
      Matcher m = replaceGTPattern.matcher(xml);
      
      String replacement;
      StringBuffer intermXml = new StringBuffer();
      
      
      while(m.find()){
      
          replacement = ">"+m.group(0).substring(1).replaceAll(">", ";&gt");
      
      
          m.appendReplacement(intermXml,replacement);
      
      
          }
      
      
          m.appendTail(intermXml);
      
      Pattern replaceLTPattern = Pattern.compile("<(.[^>]*)(<)+");
      
      m = replaceLTPattern.matcher(intermXml);
      
      StringBuffer finalXml = new StringBuffer();
      
      while(m.find()){
      
          replacement = m.group(0).substring(0,m.group(0).length()-1).replaceAll("<", ";&lt").concat("<");
      
      
          m.appendReplacement(finalXml,replacement);
      
      
          }
      
          m.appendTail(finalXml);
      
          System.out.println(finalXml);
      
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-29
        • 1970-01-01
        相关资源
        最近更新 更多