Java XML - 将字符转换为实体

arc*_*hos 0 java xml xslt entity

我有以下 XML:

<root><super-head>Text ?? and "more" ??</super-head></root>
Run Code Online (Sandbox Code Playgroud)

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

? = &star;
? = &heart;
" = &quot;
? = &quest;
- = &hyphen;
Run Code Online (Sandbox Code Playgroud)

现在我想用它们的实体替换列表中的所有字符。最初我尝试使用正则表达式来做到这一点,但它不起作用。所以我假设必须使用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);;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我将得到以下 xml(带有转义&字符):

<root><super-head>Text ?&amp;star; and &amp;qout;more&amp;qout; &amp;heart;&amp;quest;</super-head></root>
Run Code Online (Sandbox Code Playgroud)

我如何才能以最佳方式转换它或解决我的问题?

Sta*_*r00 5

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

transformer.setOutputProperty(OutputKeys.ENCODING, Charset.US-ASCII.name());
Run Code Online (Sandbox Code Playgroud)

您的实体不起作用,因为 XML 中只定义了五个默认值。您必须在 XML 文档的开头声明它们。

<!ENTITY star     "&#9734;"> 
<!ENTITY hearts   "&#9829;"> 
      . . . 
Run Code Online (Sandbox Code Playgroud)

您可能必须使用理解 HTML 实体的 Apache 实用程序类:

String org.apache.commons.text.StringEscapeUtils.escapeHtml4(String input) 
String org.apache.commons.text.StringEscapeUtils.escapeXml10(String input)
Run Code Online (Sandbox Code Playgroud)

并将它们合并到您自己的定制EntityResolver类中。实体映射不应发生在 DOM 对象内部,而是发生在将 DOMTransformation序列化为流、写入器、字符串或字节数组的步骤中。


好的,现在是答案的编辑部分。

别。

只是不要使用外部 DTD 实体或特殊的解析技巧。让 XML 转换器使用其默认行为来解析或写出 XML。让它在 XML 输出中写出数字实体。每个浏览器或 XML 解析器都知道如何处理它们。