在 Java 中处理 XML,特别是涉及到读取或写入 XML 数据的场景时,经常会遇到需要对 XML 内容进行编码或解码的情况。特别是在涉及到 XML 元素的文本内容(InnerText)时,自动转义(或称为字符实体引用)是非常重要的,以防止 XML 解析错误或安全漏洞,比如 XML 注入攻击。

1. XML 内容的自动转义

在 Java 中,当需要将字符串写入 XML 文件时,通常需要确保这些字符串中的特殊字符被正确地转义。例如,<, >, &, "' 这些字符在 XML 中有特殊的含义,因此它们需要被转换成相应的实体引用(如 &lt;, &gt;, &amp;, &quot;, 和 &apos;)。

2. 使用 Java 标准库处理 XML

使用 org.w3c.dom

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class XmlExample {
    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.newDocument();

        Element root = doc.createElement("root");
        doc.appendChild(root);

        Element element = doc.createElement("element");
        root.appendChild(element);

        // 使用 Text 节点添加内容,并自动转义特殊字符
        element.appendChild(doc.createTextNode("<example> & text"));

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(System.out);
        transformer.transform(source, result);
    }
}

使用 javax.xml.bind (JAXB)

如果使用 JAXB 来序列化 Java 对象到 XML,JAXB 会自动处理字符的转义

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class JAXBExample {
    public static void main(String[] args) throws Exception {
        JAXBContext context = JAXBContext.newInstance(MyObject.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        MyObject obj = new MyObject();
        obj.setContent("<example> & text");
        marshaller.marshal(obj, System.out);
    }
}

3. 手动处理转义和反转义

如果需要手动处理字符串的转义和反转义,可以使用 Apache Commons Text 或手动编写方法:

import org.apache.commons.text.StringEscapeUtils;

public class ManualEscape {
    public static void main(String[] args) {
        String original = "<example> & text";
        String escaped = StringEscapeUtils.escapeXml10(original); // Apache Commons Text 库进行转义
        System.out.println("Escaped: " + escaped); // 输出: &lt;example&gt; &amp; text
    }
}

或者手动实现:

public class ManualEscape {
    public static String escapeXml(String input) {
        return input.replace("&", "&amp;")
                     .replace("<", "&lt;")
                     .replace(">", "&gt;")
                     .replace("\"", "&quot;")
                     .replace("'", "&apos;");
    }
    public static void main(String[] args) {
        String original = "<example> & text";
        String escaped = escapeXml(original); // 手动转义
        System.out.println("Escaped: " + escaped); // 输出: &lt;example&gt; &amp; text
    }
}

结论

在 Java 中处理 XML 时,确保对特殊字符进行

更多推荐