XStream 转化XML时候不能支持CDATA标签

XStream 转化XML时候不能支持CDATA标签导致部分字符被转义。



import java.io.IOException;
import java.io.Writer;

import org.apache.commons.lang.StringUtils;

import com.thoughtworks.xstream.core.util.FastStack;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

public class MyPrettyPrintWriter implements ExtendedHierarchicalStreamWriter {

private final QuickWriter writer;
private final FastStack elementStack = new FastStack(16);
private final char[] lineIndenter;

private boolean tagInProgress;
private int depth;
private boolean readyForNewLine;
private boolean tagIsEmpty;
private boolean breakLine = false; // 是否换行

private static final char[] AMP = "&".toCharArray();
private static final char[] LT = "<".toCharArray();
private static final char[] GT = ">".toCharArray();
private static final char[] SLASH_R = " ".toCharArray();
private static final char[] QUOT = """.toCharArray();
private static final char[] APOS = "&apos;".toCharArray();
private static final char[] CLOSE = "</".toCharArray();

public TpaicPrettyPrintWriter(Writer writer, char[] lineIndenter, boolean breakLine, boolean needXMLHead, String encoding) throws IOException {
this.writer = new QuickWriter(writer);
this.lineIndenter = lineIndenter;
this.breakLine = breakLine;

// 增加XML头
String xmlHeader = "<?xml version=\"1.0\" encoding=\"" + (StringUtils.isNotBlank(encoding) ? encoding : "GBK") + "\"?>";
if (needXMLHead && breakLine) {
writer.write(xmlHeader + "\n");
}

if (needXMLHead && !breakLine) {
writer.write(xmlHeader);
}
}

public TpaicPrettyPrintWriter(Writer writer, boolean breakLne, boolean needXMLHead, String encoding) throws IOException {
// this(writer, new char[] { ' ', ' ' }); // 节点之间以空格分隔
this(writer, breakLne ? new char[] { ' ', ' ' } : new char[] {}, breakLne, needXMLHead, encoding);
}

public TpaicPrettyPrintWriter(Writer writer, boolean breakLne) throws IOException {
// this(writer, new char[] { ' ', ' ' }); // 节点之间以空格分隔
this(writer, breakLne ? new char[] { ' ', ' ' } : new char[] {}, breakLne, true, "GBK");
}

public void startNode(String name) {
tagIsEmpty = false;
finishTag();
writer.write('<');
writer.write(name);
elementStack.push(name);
tagInProgress = true;
depth++;
readyForNewLine = true;
tagIsEmpty = true;
}

@SuppressWarnings("unchecked")
public void startNode(String name, Class clazz) {
startNode(name);
}

public void setValue(String text) {
readyForNewLine = false;
tagIsEmpty = false;
finishTag();

writeText(writer, text);
}

public void addAttribute(String key, String value) {
writer.write(' ');
writer.write(key);
writer.write('=');
writer.write('"');
writeAttributue(writer, value);
writer.write('"');
}

protected void writeAttributue(QuickWriter writer, String text) {
int length = text.length();
for (int i = 0; i < length; i++) {
char c = text.charAt(i);
switch (c) {
case '&':
this.writer.write(AMP);
break;
case '<':
this.writer.write(LT);
break;
case '>':
this.writer.write(GT);
break;
case '"':
this.writer.write(QUOT);
break;
case '\'':
this.writer.write(APOS);
break;
case '\r':
this.writer.write(SLASH_R);
break;
default:
this.writer.write(c);
}
}
}

protected void writeText(QuickWriter writer, String text) {
int length = text.length();
String CDATAPrefix = "<![CDATA[";

if (!text.startsWith(CDATAPrefix)) {
for (int i = 0; i < length; i++) {
char c = text.charAt(i);
switch (c) {
case '&':
this.writer.write(AMP);
break;
case '<':
this.writer.write(LT);
break;
case '>':
this.writer.write(GT);
break;
case '"':
this.writer.write(QUOT);
break;
case '\'':
this.writer.write(APOS);
break;
case '\r':
this.writer.write(SLASH_R);
break;
default:
this.writer.write(c);
}
}
}

else {
for (int i = 0; i < length; i++) {
char c = text.charAt(i);
this.writer.write(c);
}
}
}

public void endNode() {
depth--;
if (tagIsEmpty) {
writer.write('/');
readyForNewLine = false;
finishTag();
elementStack.popSilently();
} else {
finishTag();
writer.write(CLOSE);
writer.write((String) elementStack.pop());
writer.write('>');
}
readyForNewLine = true;
if (depth == 0) {
writer.flush();
}
}

private void finishTag() {
if (tagInProgress) {
writer.write('>');
}
tagInProgress = false;
if (readyForNewLine) {
endOfLine();
}
readyForNewLine = false;
tagIsEmpty = false;
}

protected void endOfLine() {
if (breakLine) {// 节点是否换行,不换所有节点一行显示
writer.write('\n');
}
for (int i = 0; i < depth; i++) {
writer.write(lineIndenter);
}
}

public void flush() {
writer.flush();
}

public void close() {
writer.close();
}

public HierarchicalStreamWriter underlyingWriter() {
return this;
}

}






import java.io.IOException;
import java.io.Writer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class MyXppDriver extends XppDriver {
public static final Log logger = LogFactory.getLog(TpaicXppDriver.class);

private boolean breakLine = false; // 是否换行

private boolean needXmlHeader = true;

private String encoding = "GBK"; // xml头编码方式

public TpaicXppDriver(boolean breakLine, boolean needXmlHeader, String encoding) {
this.breakLine = breakLine;
this.needXmlHeader = needXmlHeader;
this.encoding = encoding;
}

public TpaicXppDriver() {
this(false, true, "GBK");
}

@Override
public HierarchicalStreamWriter createWriter(Writer out) {
HierarchicalStreamWriter writer = null;
try {
writer = new MyPrettyPrintWriter(out, breakLine, needXmlHeader, encoding);
} catch (IOException e) {
logger.error(e);
}
return writer;
}
}





public static String objectToXmlSupportCDATA(Object object, boolean format, boolean needXmlHead, String encoding) {
XStream xstream = new XStream(new MyXppDriver(format, needXmlHead, encoding));
xstream.autodetectAnnotations(true);
return xstream.toXML(object);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值