`
xining
  • 浏览: 39761 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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 = "&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);
    }
分享到:
评论

相关推荐

    Java用xStream拼接xml

    xStream的核心功能是基于对象关系映射(ORM)的概念,它自动将Java类的实例转换为XML文档,并能将XML文档转换回相应的Java对象。 **xStream的使用** 1. **添加依赖** 在使用xStream之前,你需要将其作为项目依赖...

    XStream解析XML实例

    在Android开发中,XStream同样适用,但需要注意的是,由于Android的安全限制,不能直接使用`XStream`的默认实现。可以使用如`Xpp3Driver`这样的安全驱动来替代: ```java xstream = new XStream(new Xpp3Driver());...

    XStream解析xml demo

    同样,XStream也支持从XML字符串反序列化回Java对象: ```java String xmlInput = "&lt;person&gt;&lt;name&gt;Bob&lt;/name&gt;&lt;age&gt;25&lt;/age&gt;&lt;/person&gt;"; Person deserializedPerson = (Person) xstream.fromXML(xmlInput); System....

    Xstream生产xml和解析xml

    XStream支持多种XML解析器,包括XPP3和JAXP DOM,用户可以根据性能和兼容性需求选择合适的解析器。例如,使用XPP3时,可以通过`new XStream(newXppDriver())`创建XStream实例;若使用JAXP DOM,则调用`new XStream...

    利用XStream读写xml文件

    XStream支持广泛的Java类型,并且易于集成到现有的Java应用程序中。 ### 示例代码分析 #### 1. XML文件结构解析 给定的XML文件描述了一个公司的组织结构,包括部门和员工的信息。具体结构如下: - `&lt;company&gt;`:...

    使用xstream解析xml,xml与pojo的双向转化,完整的java 工程

    XStream是JVM平台上的一个开源库,由XStream Software公司开发,它通过简单的API将Java对象序列化为XML,同时也能将XML反序列化回Java对象。这个过程非常便捷,使得开发者可以快速地处理XML数据,而无需手动编写大量...

    xstream对象与xml转换

    在Java编程语言中,XStream库提供了一个简单且强大的机制,用于将Java对象序列化为XML,反之亦然。这使得在存储数据、传输数据或持久化对象时非常方便。本教程将深入探讨XStream库及其在Java中的使用,通过实际的...

    com.thoughtworks.xstream.XStream操作XML和java对象的一些用法

    首先,XStream是一个强大的库,它由Pete Gyford开发,用于将Java对象序列化为XML,同时也能将XML反序列化为Java对象。它的主要优点是代码简洁,易于理解,同时也支持自定义转换规则,使得XML的结构可以更贴近业务...

    Xstream解析xml

    // "playbill"是XML中的标签,Playbill是对应的Java类 ``` 这里`Playbill`是我们假设的数据模型类,它包含了与XML文件对应的数据字段。 接下来,我们加载XML文件。在Java中,我们可以使用`FileInputStream`或`...

    xStream转换xml和json源码

    xStream是一个轻量级的Java库,用于将Java对象序列化为XML,同时也能将XML反序列化回Java对象。这个强大的工具同样支持JSON格式,使得在Java应用程序中处理XML和JSON数据变得非常便捷。本篇文章将深入探讨xStream...

    xstream将xml文档转换成json对象

    在这个场景中,我们将探讨如何使用XStream将XML文档转换成Java对象,进而转化为JSON对象。 首先,我们需要引入XStream库。XStream的核心功能是能够将Java对象和XML之间的映射自动化,极大地简化了序列化和反序列化...

    XStream XML解析

    **XStream XML解析** XStream 是一个开源的 Java 库,它提供了一种简单而有效的方式来将 Java 对象序列化为 XML 和从 XML 反序列化回 Java 对象。这个库的强大之处在于其简洁的API和对复杂Java对象模型的处理能力。...

    XStream解析xml 转换成对象案例

    而XStream是一个Java库,它能够将Java对象序列化为XML,反之也能将XML反序列化回Java对象,极大地简化了Java与XML之间的交互。本篇文章将深入探讨如何使用XStream进行XML到对象的转换,并提供一个实际的案例。 首先...

    XStream XML与Json转换

    在缺省情况下,XStream不需要配置映射关系,对象和字段将映射为同名XML元素。但是当对象和字段名与XML中的元素名不同时,XStream支持指定别名。XStream支持以方法调用的方式,或是Java 标注的方式指定别名。 ...

    xstream轻松解析xml到java对象

    XStream默认会使用类名作为XML元素的标签,字段名作为属性。但你可以自定义这种映射,例如: ```java xstream.alias("customName", YourJavaClass.class); xstream.useAttributeFor(YourJavaClass.class, "field...

    xstream解析xml

    XStream是一个轻量级、高性能的Java库,它能够将Java对象序列化为XML,反之也能将XML反序列化为Java对象。这使得XML数据与Java对象之间的转换变得非常简单。 **XStream库的核心特性:** 1. **直观的映射:** ...

    xStream 实现xml与 java对象的转换

    【标题】:“xStream 实现xml与 java对象的转换” 在Java开发中,XML作为一种常见的数据交换格式,常用于存储和传输数据。然而,XML与Java对象之间的转换并不总是直观和简便的。这时,xStream库应运而生,它提供了...

    JAVA对象转换成XML(CDATA)

    总的来说,通过自定义HierarchicalStreamWriter,我们可以精确地控制XML的生成,包括在需要的时候使用CDATA来包裹可能引起解析问题的文本。这种方式允许我们在XML中安全地包含任何类型的数据,而不会因为特殊字符...

    xml解析及使用XStream实现javaBean与xml之间的转换

    XStream不仅支持XML,还内置了对JSON的支持。只需添加额外的转换器,如使用Jettison库,即可实现JavaBean与JSON的转换。 5. **实战演示** 在`xmlAnalysis`文件夹中,可能包含了一个简单的Java程序,演示了如何...

    使用XStream操作xml教程

    XStream库提供了一个优雅的方式来将Java对象转换为XML,反之亦然,使得处理XML数据变得更加简单。本教程将深入探讨如何使用XStream进行XML操作。 一、XStream简介 XStream是一个开源库,由Johannes Link开发,它...

Global site tag (gtag.js) - Google Analytics