Java XML - 将字符转换为实体

时间:2018-04-19 12:31:53

标签: java xml xslt entity

我有以下XML:

<root><super-head>Text ​☆ and "more" ♥?</super-head></root>

还有一些实体(实际上超过400件):

☆ = &star;
♥ = &heart;
" = &quot;
? = &quest;
- = &hyphen;

现在我想用它们的实体替换列表中的所有字符。最初我尝试使用正则表达式执行此操作,但它不起作用。所以我假设必须使用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 ​&amp;star; and &amp;qout;more&amp;qout; &amp;heart;&amp;quest;</super-head></root>

如何将其转换为最佳方式或解决我的问题?

1 个答案:

答案 0 :(得分:3)

如果将输出编码设置为US-ASCII,则会强制所有非ascii使用模式&#nnnn;使用实体的代码点进行编码。

transformer.setOutputProperty(OutputKeys.ENCODING, Charset.US-ASCII.name());

您的实体无法正常工作,因为XML中只定义了五个默认值。您必须在XML文档的开头声明它们。

<!ENTITY star     "&#9734;"> 
<!ENTITY hearts   "&#9829;"> 
      . . . 

您可能必须使用了解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解析器都知道如何处理它们。