元素文本中带有“&”的 XML 解析问题

Posted

技术标签:

【中文标题】元素文本中带有“&”的 XML 解析问题【英文标题】:XML parsing issue with '&' in element text 【发布时间】:2011-04-19 19:03:39 【问题描述】:

我有以下代码:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(inputXml)));

解析步骤被抛出:

SAXParseException: The entity name must immediately follow 
                   the '&' in the entity reference

由于我的inputXml 中有以下“&”:

<Line1>Day & Night</Line1>

我无法控制入站 XML。我怎样才能安全/正确地解析这个?

【问题讨论】:

【参考方案1】:

很简单,输入“XML”不是有效的 XML。实体应该被编码,即:

<Line1>Day &amp; Night</Line1>

基本上,除了告诉 XML 供应商他们给你垃圾并让 他们 修复它之外,没有“正确”的方法来解决这个问题。如果您处于必须处理的可怕情况,那么您采取的方法可能取决于您期望获得的价值范围。

如果文档中根本没有实体,则在处理之前将&amp;amp;amp; 的正则表达式替换为&amp;amp;amp; 就可以了。但是,如果他们正确发送了一些实体,您需要从匹配中排除这些实体。如果他们真的想发送实体代码(即发送&amp;amp;amp;,但意思是&amp;amp;amp;),那么您将完全不走运。

但是,嘿 - 无论如何,这都是供应商的错,如果您修复无效输入的尝试不是他们想要的,他们可以做一件简单的事情来解决这个问题。 :-)

【讨论】:

啊,谢谢。我怕是这样。听起来好像打了几个电话就可以了:) 大家好,我遇到了类似的问题,但是在处理之前将“&”替换为“&”(即 StringEscapeUtils.unescapehtml() )不能解决我的问题吗?【参考方案2】:

您的输入 XML 不是有效的 XML;不幸的是,您实际上无法使用 XML 解析器来解析它。

在将文本传递给 XML 解析器之前,您需要对其进行预处理。虽然您可以进行字符串替换,将'&amp;amp; ' 替换为'&amp;amp; ',但这不会捕获输入中&amp; 的每一次出现,但您可能会想出一些办法。

【讨论】:

【参考方案3】:

xml解析前我用过Tidy框架

final StringWriter errorMessages = new StringWriter();
final String res = new TidyChecker().doCheck(html, errorMessages);
...
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(addRoot(html))));  
...

一切都好

【讨论】:

【参考方案4】:

inputXML 是一个字符串吗?然后使用这个:

inputXML = inputXML.replaceAll("&\\s+", "&amp;");

【讨论】:

好主意,但如上所述,需要注意文档中的实体。 试试这个具有负面预测的解决方案:***.com/a/1944951/107277 这应该是 inputXML = inputXML.replaceAll("&\\s+", "& ");

以上是关于元素文本中带有“&”的 XML 解析问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery $().find 解析带有命名空间的 XML

Mybatis中的CDATA标签

Web Service(上)

mapper中的CDATA标签的用法

Mybatis中的CDATA标签的用法

如何使用 &nbsp 元素将我的字符串解析为 XML?