XStream使用toXML(Object,StreamWriter)缺少换行符

时间:2013-01-31 18:59:52

标签: java newline xstream

我尝试使用Xstream序列化Java中的对象列表,我的核心代码是:

//register alias
xstream.alias("category", ServerCategory.class);

//register converter
xstream.registerConverter(new ServerCategoryConverter());

// get all categories
List<ServerCategory> categoryList = categoryDao.getAllEager();

// serialize all categories
for(ServerCategory category : categoryList) {
    xstream.toXML(category, streamWriter);
}

这很好用,但我在</category> - 标签之后没有换行,这似乎与xml规范冲突导致每个读者都在此行中断。 有没有解决这个问题?

1 个答案:

答案 0 :(得分:2)

您当前的代码将生成以下内容:

<category>
    <id>1</id>
    <name>One</name>
    <description>One</description>
    <syncversion>V1</syncversion>
    <parents/>
  </category>
  <category>
    <id>2</id>
    <name>Two</name>
    <description>Two</description>
    <syncversion>V1</syncversion>
    <parents>
      <parent>1</parent>
    </parents>
  </category>

这是无效的xml,因为它应该有一个根元素(这个xml有多个根元素类别) 理想情况下,您应该生成这样的。 您可以在浏览器中打开以下内容。

<list> <!-- one root element required!!-->
  <category>
    <id>1</id>
    <name>One</name>
    <description>One</description>
    <syncversion>V1</syncversion>
    <parents/>
  </category>
  <category>
    <id>2</id>
    <name>Two</name>
    <description>Two</description>
    <syncversion>V1</syncversion>
    <parents>
      <parent>1</parent>
    </parents>
  </category>
<list>

需要做的不是

for(ServerCategory category : categoryList) {
    xstream.toXML(category, streamWriter);
}

你应该序列化整个列表

xstream.toXML(categoryList, streamWriter);

并且应使用

覆盖您的ServerCategoryConverter canCovert()
public boolean canConvert(Class foo) {
            //dont use this converter for the Arraylist. Arraylist will be handeld by the default converter
            if (foo.getName().equals("java.util.ArrayList")) {
                return false;
            }
            return true;
        }

我已附上我的完整代码供参考。它适用于上述修复:

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

public class XSTReamTest {
    /*
 * ExpertService.class
 */
    public static void main(String args[]) throws Exception {
        XSTReamTest tst = new XSTReamTest();
        tst.createXmlExport();
    }

    public File createXmlExport() throws Exception {
        XStream xstream = new XStream();
        File xmlExportFile = null;
        BufferedOutputStream outputStream = null;
        OutputStreamWriter streamWriter = null;

        try {
            xmlExportFile = new File("easylearncards1_exportRequest_.xml");
            System.out.println("Path = " + xmlExportFile.getAbsolutePath());

            outputStream = new BufferedOutputStream(new FileOutputStream(xmlExportFile));
            streamWriter = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
            exportCategories(xstream, streamWriter);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                streamWriter.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return xmlExportFile;
    }

    private void exportCategories(XStream xstream, OutputStreamWriter streamWriter) {
        // register alias
        xstream.alias("category", ServerCategory.class);

        // register converter
        xstream.registerConverter(new ServerCategoryConverter());

        // get all categories
        List<ServerCategory> categoryList = new ArrayList<ServerCategory>();

        ServerCategory root = new ServerCategory("1", "One", "One", "V1", null);
        ServerCategory child1 = new ServerCategory("2", "Two", "Two", "V1", new ServerCategory[]{root});
        ServerCategory child2 = new ServerCategory("3", "Three", "Three", "V1", new ServerCategory[]{root});
        ServerCategory child3 = new ServerCategory("4", "Four", "Four", "V1", new ServerCategory[]{child1, child2});

        categoryList.add(root);
        categoryList.add(child1);
        categoryList.add(child2);
        categoryList.add(child3);

        // convert all categories
//        for (ServerCategory category : categoryList) {
//            xstream.toXML(category, streamWriter);
//        }
        xstream.toXML(categoryList, streamWriter);
    }

    static class ServerCategory {
        String id;
        String name;
        String description;
        String syncVersion;
        ServerCategory parents[];

        ServerCategory(String id, String name, String description, String syncVersion, ServerCategory[] parents) {
            this.id = id;
            this.name = name;
            this.description = description;
            this.syncVersion = syncVersion;
            this.parents = parents;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getSyncVersion() {
            return syncVersion;
        }

        public void setSyncVersion(String syncVersion) {
            this.syncVersion = syncVersion;
        }

        public ServerCategory[] getParents() {
            return parents;
        }

        public void setParents(ServerCategory[] parents) {
            this.parents = parents;
        }
    }
/*
 * ServerCategoryConverter.class
 */

    static class ServerCategoryConverter implements Converter {

        public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {

            ServerCategory category = (ServerCategory) value;

            writer.startNode("id");
            writer.setValue(category.getId().toString());
            writer.endNode();

            writer.startNode("name");
            writer.setValue(category.getName());
            writer.endNode();

            writer.startNode("description");
            writer.setValue(category.getDescription());
            writer.endNode();

            writer.startNode("syncversion");
            writer.setValue(category.getSyncVersion().toString());
            writer.endNode();

            writer.startNode("parents");
            if (category.getParents() != null) {
                for (ServerCategory parent : category.getParents()) {
                    writer.startNode("parent");
                    writer.setValue(parent.getId().toString());
                    writer.endNode();

                }
            }
            writer.endNode();

        }

        public java.lang.Object unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader hierarchicalStreamReader, com.thoughtworks.xstream.converters.UnmarshallingContext unmarshallingContext) {
            return null;
        }

        public boolean canConvert(Class foo) {
            if (foo.getName().equals("java.util.ArrayList")) {
                return false;
            }
            return true;
        }

    }
}