XStreamは、アンダースコアを含むタグをダブらせて、、2個のアンダースコアにしてしまう!!そういう仕様で規則だ。
これを避けるには、
XStream インスタンス生成を、
Stream stream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_"));
でということだが、問題があって、、、
これと、CDATAセクションを書くようにする方法を
new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_")){ public HierarchicalStreamWriter createWriter(Writer out){ return new PrettyPrintWriter(writer){ protected void writeText(QuickWriter w, String text){ if (text.indexOf("<") >= 0 || text.indexOf(">") >= 0 || text.indexOf("&") >= 0 || text.indexOf("!") >= 0 || text.indexOf("'") >= 0 || text.indexOf("\"") >= 0 ){ w.write("<![CDATA["); w.write(text); w.write("]]>"); }else{ w.write(text); } } }; } }
と書いてしまうと、CDATA セクションのwriter が優先されて、相変わらず、ダブルのアンダースコアになってしまう!!
しかたなく、XppDriver または DomDriver 継承クラスを準備して以下のものを用意して使う。
import java.io.OutputStreamWriter; import java.io.Writer; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.DomDriver; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; /** * CdataDomDriver. */ public final class CdataDomDriver extends DomDriver{ private OutputStreamWriter outwriter; /** * コンストラクタ. * @param writer OutputStreamWriter */ public CdataDomDriver(OutputStreamWriter writer){ super("UTF-8", new XmlFriendlyNameCoder("_-", "_")); outwriter = writer; } @Override public HierarchicalStreamWriter createWriter(Writer out){ return new PrettyPrintWriter(outwriter, new XmlFriendlyNameCoder("_-", "_")){ protected void writeText(QuickWriter writer, String text){ if (text.indexOf("<") >= 0 || text.indexOf(">") >= 0 || text.indexOf("&") >= 0 || text.indexOf("!") >= 0 || text.indexOf("'") >= 0 || text.indexOf("\"") >= 0 ){ writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); }else{ writer.write(text); } } }; } }
あるいは、、、
import java.io.OutputStreamWriter; import java.io.Writer; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import com.thoughtworks.xstream.io.xml.XppDriver; /** * CdataXppDriver. */ public final class CdataXppDriver extends XppDriver{ private OutputStreamWriter outwriter; /** * コンストラクタ. * @param writer OutputStreamWriter */ public CdataXppDriver(OutputStreamWriter writer){ super(new XmlFriendlyNameCoder("_-", "_")); outwriter = writer; } @Override public HierarchicalStreamWriter createWriter(Writer out){ return new PrettyPrintWriter(outwriter, new XmlFriendlyNameCoder("_-", "_")){ protected void writeText(QuickWriter writer, String text){ if (text.indexOf("<") >= 0 || text.indexOf(">") >= 0 || text.indexOf("&") >= 0 || text.indexOf("!") >= 0 || text.indexOf("'") >= 0 || text.indexOf("\"") >= 0 ){ writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); }else{ writer.write(text); } } }; } }
そして、、、
try(OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("out.xml"), "UTF-8")){ writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); XStream stream = new XStream(new CdataXppDriver(writer));
とする。