我有以下XML:
<root><super-head>Text ☆ and "more" ♥?</super-head></root>
还有一些实体(实际上超过400件):
☆ = ☆
♥ = &heart;
" = "
? = ?
- = ‐
现在我想用它们的实体替换列表中的所有字符。最初我尝试使用正则表达式执行此操作,但它不起作用。所以我假设必须使用Java或XSLT(我只能在这里使用1.0)。
在Java中我尝试了以下内容:
public void replaceStringForNode(Node node, Map<String, String> map) {
// replace for all attributes
NamedNodeMap attributes = node.getAttributes();
for (int i = 0, l = attributes.getLength(); i < l; i++) {
Node attr = attributes.item(i);
String content = attr.getNodeValue();
for (Entry<String, String> entry : map.entrySet()) {
content = content.replace(entry.getKey(), entry.getValue());
}
attr.setNodeValue(content);
}
// check all child nodes
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node currentNode = nodeList.item(i);
int type = currentNode.getNodeType();
if (type == Node.ELEMENT_NODE) {
this.replaceStringForNode(currentNode, map);
} else if (type == Node.TEXT_NODE) {
String content = currentNode.setNodeValue();
for (Entry<String, String> entry : map.entrySet()) {
content = content.replace(entry.getKey(), entry.getValue());
}
currentNode.setNodeValue(content);;
}
}
}
但在这种情况下,我将获得以下xml(带有转义的&
个字符):
<root><super-head>Text &star; and &qout;more&qout; &heart;&quest;</super-head></root>
如何将其转换为最佳方式或解决我的问题?
答案 0 :(得分:3)
如果将输出编码设置为US-ASCII
,则会强制所有非ascii使用模式&#nnnn;
使用实体的代码点进行编码。
transformer.setOutputProperty(OutputKeys.ENCODING, Charset.US-ASCII.name());
您的实体无法正常工作,因为XML中只定义了五个默认值。您必须在XML文档的开头声明它们。
<!ENTITY star "☆">
<!ENTITY hearts "♥">
. . .
您可能必须使用了解HTML实体的Apache实用程序类:
String org.apache.commons.text.StringEscapeUtils.escapeHtml4(String input)
String org.apache.commons.text.StringEscapeUtils.escapeXml10(String input)
并将它们合并到您自己的自定义EntityResolver
课程中。实体映射不应该发生在DOM对象内部,而应发生在Transformation
步骤,其中DOM被序列化为流,写入器,字符串或字节数组。
好的,现在是答案的编辑部分。
唐&#39;吨。
不要使用外部DTD实体或特殊解析黑客。让XML转换器使用其默认行为来解析或写出XML。让它在XML输出中写出数字实体。每个浏览器或XML解析器都知道如何处理它们。