【发布时间】:2017-02-21 04:37:41
【问题描述】:
我正在处理一个从输入生成 XML 的遗留系统。此输入有时包含垂直制表符 控制字符。然后这些字符在生成的 XML 中进行编码。垂直制表符可以写成 Java 字符串\u000B。这是一个示例代码,说明了发生的情况(原始过程从输入中获取字符串,并在没有任何预处理的情况下创建文本节点):
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(new InputSource(new StringReader("<xml></xml>")));
Element sample = doc.createElement("sample");
sample.appendChild(doc.createTextNode("Hello\u000BWorld"));
doc.getDocumentElement().appendChild(sample);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(System.out, "UTF-8")));
这会生成一个无效的 XML 文档:
<?xml version="1.0" encoding="UTF-8"?><xml>
<sample>HelloWorld</sample>
</xml>
现在我需要使用相同的解析器,即:
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(new InputSource(new StringReader(theResultFromAbove)));
并再次生成 Document 实例。但这失败了:
[Fatal Error] :2:23: Character reference "&#
org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 23; Character reference "&#
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
我可以控制第二个解析器,所以我可以在解析输出之前搜索和替换&#11;。我还对生成 XML 的代码进行了一些控制,因此我可以在所有这些发生之前简单地删除垂直选项卡。
但是,我可以做些什么来添加或实现&#11;实体,这样解析器不仅可以对其进行编码,而且可以对其进行正确解码? p>
【问题讨论】: