gpt4 book ai didi

java - 转义 XML 字符而不转义 CDATA 标记

转载 作者:太空宇宙 更新时间:2023-11-04 12:20:29 24 4
gpt4 key购买 nike

我正在尝试使用 JAXB 序列化一个类,该类具有一些 CDATA 字段,以及一些包含需要转义的特殊字符(包括 < 和 >)的字段。问题是我无法让转义处理在这两种情况下正常工作。

使用自定义 CDATA 适配器,如果我在编码器上设置以下属性,

jaxbMarshaller.setProperty(CharacterEscapeHandler.class.getName(),
(CharacterEscapeHandler) (ch, start, length, isAttVal, out) -> out.write(ch, start, length));

我得到:

<key1><![CDATA[Test]]></key1> # What I want
<key2>some_>_value</key2> # Invalid XML

如果我删除该属性并让 jaxb 处理其自己的转义,我会得到:

<key1>&lt;![CDATA[Test]]&gt;  # Not what I want
<key2>some_&lt;_value</key2> # What I want

但我需要的是:

<key1><![CDATA[Test]]></key1>
<key2>some_&lt;_value</key2>

有什么方法可以让我的转义处理函数以这种方式运行吗?

最佳答案

您可以使用com.sun.xml.bind.marshaller.CharacterEscapeHandler接口(interface)来解决您的问题。

示例 Java 类:

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class AA {

String B;
String C;


public String getB() {
return B;
}

@XmlElement
public void setB(String b) {
B = b;
}

@Override
public String toString() {
return "AA [B=" + B + ", C=" + C + ", D=" + D + "]";
}

public String getC() {
return C;
}

@XmlElement
public void setC(String c) {
C = c;
}

public String getD() {
return D;
}

@XmlElement
public void setD(String d) {
D = d;
}

String D;
}

示例 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<aa>
<b>Title of Feed Item</b>
<c>some_>_value</c>
<d>
<![CDATA[Test]]>
</d>
</aa>

序列化调用:

AA ref = new AA();
ref.setB("Title of Feed Item");
ref.setC("some_>_value");
ref.setD("<![CDATA[Test]]>");
File file = new File("Test.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(AA.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
final Map<String, String> replacement=new HashMap<String, String>();
replacement.put(">", "&gt;");
replacement.put("<", "&lt;");
final Pattern pattern=Pattern.compile("[<|>]");

jaxbMarshaller.setProperty(CharacterEscapeHandler.class.getName(),
new CharacterEscapeHandler() {

@Override
public void escape(char[] arg0, int arg1, int arg2,
boolean arg3, Writer arg4) throws IOException {
if (String.valueOf(arg0).contains("CDATA"))
arg4.write(arg0, arg1, arg2);
else {
StringBuffer buffer = new StringBuffer();
Matcher matcher = pattern.matcher(String
.valueOf(arg0));
while (matcher.find()) {
matcher.appendReplacement(buffer,
replacement.get(matcher.group()));
}
matcher.appendTail(buffer);
char t[] = buffer.toString().toCharArray();
arg4.write(t, arg1, t.length);
}
}
});



jaxbMarshaller.marshal(ref, file);
jaxbMarshaller.marshal(ref, System.out);

编辑:我已使用括号的正则表达式修改了代码。

对于正则表达式示例,我已引用 this link

关于java - 转义 XML 字符而不转义 CDATA 标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38899525/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com