-/*\r
- * basic xml exporter\r
- *\r
- * License : The MIT License\r
- * Copyright(c) 2010 MikuToga Partners\r
- */\r
-\r
-package jp.sourceforge.mikutoga.xml;\r
-\r
-import java.io.BufferedWriter;\r
-import java.io.Closeable;\r
-import java.io.Flushable;\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.io.OutputStreamWriter;\r
-import java.nio.charset.Charset;\r
-import javax.xml.bind.DatatypeConverter;\r
-\r
-/**\r
- * 各種XMLエクスポータの基本機能。\r
- * UCS4は未サポート。\r
- */\r
-public class BasicXmlExporter {\r
-\r
- /** デフォルトエンコーディング。 */\r
- private static final Charset CS_UTF8 = Charset.forName("UTF-8");\r
-\r
- /** デフォルトの改行文字列。 */\r
- private static final String LF = "\n"; // 0x0a\r
- /** デフォルトのインデント単位。 */\r
- private static final String DEFAULT_INDENT_UNIT = "\u0020\u0020";\r
-\r
- private static final char[] HEXCHAR_TABLE = {\r
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\r
- 'A', 'B', 'C', 'D', 'E', 'F',\r
- };\r
-\r
- static{\r
- assert HEXCHAR_TABLE.length == 16;\r
- }\r
-\r
-\r
- private final Appendable appendable;\r
-\r
- private String newline = LF;\r
- private String indentUnit = DEFAULT_INDENT_UNIT;\r
-\r
- private int indentNest = 0;\r
- private boolean basicLatinOnlyOut = true;\r
-\r
-\r
- /**\r
- * コンストラクタ。\r
- * 文字エンコーディングはUTF-8が用いられる。\r
- * @param stream 出力ストリーム\r
- */\r
- public BasicXmlExporter(OutputStream stream){\r
- this(stream, CS_UTF8);\r
- return;\r
- }\r
-\r
- /**\r
- * コンストラクタ。\r
- * @param stream 出力ストリーム\r
- * @param charSet 文字エンコーディング指定\r
- */\r
- public BasicXmlExporter(OutputStream stream, Charset charSet){\r
- this(\r
- new BufferedWriter(\r
- new OutputStreamWriter(stream, charSet)\r
- )\r
- );\r
- return;\r
- }\r
-\r
- /**\r
- * コンストラクタ。\r
- * @param appendable 文字列出力\r
- */\r
- public BasicXmlExporter(Appendable appendable){\r
- super();\r
- this.appendable = appendable;\r
- return;\r
- }\r
-\r
- /**\r
- * ASCIIコード相当(UCS:Basic-Latin)の文字か否か判定する。\r
- * @param ch 判定対象文字\r
- * @return Basic-Latin文字ならtrue\r
- */\r
- public static boolean isBasicLatin(char ch){\r
- if(ch <= 0x7f) return true;\r
- return false;\r
- }\r
-\r
- /**\r
- * 改行文字列を設定する。\r
- * @param newLine 改行文字列\r
- * @throws NullPointerException 引数がnull\r
- */\r
- public void setNewLine(String newLine) throws NullPointerException{\r
- if(newLine == null) throw new NullPointerException();\r
- this.newline = newLine;\r
- return;\r
- }\r
-\r
- /**\r
- * BasicLatin文字だけで出力するか設定する。\r
- * BasicLatin以外の文字(≒日本語)をそのまま出力するか\r
- * 文字参照で出力するかの設定が可能。\r
- * コメント部中身は対象外。\r
- * @param bool BasicLatin文字だけで出力するならtrue\r
- */\r
- public void setBasicLatinOnlyOut(boolean bool){\r
- this.basicLatinOnlyOut = bool;\r
- return;\r
- }\r
-\r
- /**\r
- * BasicLatin文字だけを出力する状態か判定する。\r
- * コメント部中身は対象外。\r
- * @return BasicLatin文字だけで出力するならtrue\r
- */\r
- public boolean isBasicLatinOnlyOut(){\r
- return this.basicLatinOnlyOut;\r
- }\r
-\r
- /**\r
- * 改行文字列を設定する。\r
- * デフォルトではLF(0x0a)\nが用いられる。\r
- * @param seq 改行文字列。nullは空文字列""と解釈される。\r
- */\r
- public void setNewLine(CharSequence seq){\r
- if(seq == null) this.newline = "";\r
- else this.newline = seq.toString();\r
- return;\r
- }\r
-\r
- /**\r
- * インデント単位文字列を設定する。\r
- * デフォルトでは空白2個。\r
- * @param seq インデント単位文字列。nullは空文字列""と解釈される。\r
- */\r
- public void setIndentUnit(CharSequence seq){\r
- if(seq == null) this.indentUnit = "";\r
- else this.indentUnit = seq.toString();\r
- }\r
-\r
- /**\r
- * 可能であれば出力をフラッシュする。\r
- * @throws IOException 出力エラー\r
- */\r
- public void flush() throws IOException{\r
- if(this.appendable instanceof Flushable){\r
- ((Flushable)this.appendable).flush();\r
- }\r
- return;\r
- }\r
-\r
- /**\r
- * 可能であれば出力をクローズする。\r
- * @throws IOException 出力エラー\r
- */\r
- public void close() throws IOException{\r
- if(this.appendable instanceof Closeable){\r
- ((Closeable)this.appendable).close();\r
- }\r
- return;\r
- }\r
-\r
- /**\r
- * 1文字出力する。\r
- * @param ch 文字\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter put(char ch) throws IOException{\r
- this.appendable.append(ch);\r
- return this;\r
- }\r
-\r
- /**\r
- * 文字列を出力する。\r
- * @param seq 文字列\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter put(CharSequence seq) throws IOException{\r
- this.appendable.append(seq);\r
- return this;\r
- }\r
-\r
- /**\r
- * int値を出力する。\r
- * @param iVal int値\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- * @see java.lang.Integer#toString(int)\r
- */\r
- public BasicXmlExporter put(int iVal) throws IOException{\r
- String value = DatatypeConverter.printInt(iVal);\r
- this.appendable.append(value);\r
- return this;\r
- }\r
-\r
- /**\r
- * float値を出力する。\r
- * @param fVal float値\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- * @see java.lang.Float#toString(float)\r
- */\r
- public BasicXmlExporter put(float fVal) throws IOException{\r
- String value = DatatypeConverter.printFloat(fVal);\r
- this.appendable.append(value);\r
- return this;\r
- }\r
-\r
- /**\r
- * 改行を出力する。\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter ln() throws IOException{\r
- this.appendable.append(this.newline);\r
- return this;\r
- }\r
-\r
- /**\r
- * 改行を指定回数出力する。\r
- * @param count 改行回数。0以下の場合は何も出力しない。\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter ln(int count) throws IOException{\r
- for(int ct = 1; ct <= count; ct++){\r
- this.appendable.append(this.newline);\r
- }\r
- return this;\r
- }\r
-\r
- /**\r
- * インデントを出力する。\r
- * インデント単位文字列をネストレベル回数分出力する。\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter ind() throws IOException{\r
- for(int ct = 1; ct <= this.indentNest; ct++){\r
- put(this.indentUnit);\r
- }\r
- return this;\r
- }\r
-\r
- /**\r
- * インデントレベルを一段下げる。\r
- */\r
- public void pushNest(){\r
- this.indentNest++;\r
- return;\r
- }\r
-\r
- /**\r
- * インデントレベルを一段上げる。\r
- * インデントレベル0の状態をさらに上げようとした場合、何も起こらない。\r
- */\r
- public void popNest(){\r
- this.indentNest--;\r
- if(this.indentNest < 0) this.indentNest = 0;\r
- return;\r
- }\r
-\r
- /**\r
- * 指定された文字を16進2桁の文字参照形式で出力する。\r
- * 2桁で出力できない場合は4桁で出力する。\r
- * @param ch 文字\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putCharRef2Hex(char ch) throws IOException{\r
- if(ch > 0xff) return putCharRef4Hex(ch);\r
-\r
- char hex3 = HEXCHAR_TABLE[(ch >> 4) & 0x000f];\r
- char hex4 = HEXCHAR_TABLE[(ch ) & 0x000f];\r
-\r
- this.appendable.append("&#x");\r
- this.appendable.append(hex3);\r
- this.appendable.append(hex4);\r
- this.appendable.append(';');\r
-\r
- return this;\r
- }\r
-\r
- /**\r
- * 指定された文字を16進4桁の文字参照形式で出力する。\r
- * UCS4に伴うサロゲートペアは未サポート\r
- * @param ch 文字\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putCharRef4Hex(char ch) throws IOException{\r
- char hex1 = HEXCHAR_TABLE[(ch >> 12) & 0x000f];\r
- char hex2 = HEXCHAR_TABLE[(ch >> 8) & 0x000f];\r
- char hex3 = HEXCHAR_TABLE[(ch >> 4) & 0x000f];\r
- char hex4 = HEXCHAR_TABLE[(ch ) & 0x000f];\r
-\r
- this.appendable.append("&#x");\r
- this.appendable.append(hex1);\r
- this.appendable.append(hex2);\r
- this.appendable.append(hex3);\r
- this.appendable.append(hex4);\r
- this.appendable.append(';');\r
-\r
- return this;\r
- }\r
-\r
- /**\r
- * 要素の中身および属性値中身を出力する。\r
- * 必要に応じてXML定義済み実体文字が割り振られた文字、\r
- * コントロールコード、および非BasicLatin文字がエスケープされる。\r
- * @param content 内容\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putContent(CharSequence content)\r
- throws IOException{\r
- int length = content.length();\r
-\r
- for(int pos = 0; pos < length; pos++){\r
- char ch = content.charAt(pos);\r
- if(Character.isISOControl(ch)){\r
- putCharRef2Hex(ch);\r
- }else if( ! isBasicLatin(ch) && isBasicLatinOnlyOut()){\r
- putCharRef4Hex(ch);\r
- }else{\r
- switch(ch){\r
- case '&': this.appendable.append("&"); break;\r
- case '<': this.appendable.append("<"); break;\r
- case '>': this.appendable.append(">"); break;\r
- case '"': this.appendable.append("""); break;\r
- case '\'': this.appendable.append("'"); break;\r
- case '\u00a5': this.appendable.append('\u005c\u005c'); break;\r
- default: this.appendable.append(ch); break;\r
- }\r
- }\r
- }\r
-\r
- return this;\r
- }\r
-\r
- /**\r
- * 属性値を出力する。\r
- * @param attrName 属性名\r
- * @param content 属性内容\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putAttr(CharSequence attrName,\r
- CharSequence content)\r
- throws IOException{\r
- put(attrName).put('=').put('"').putContent(content).put('"');\r
- return this;\r
- }\r
-\r
- /**\r
- * int型属性値を出力する。\r
- * @param attrName 属性名\r
- * @param iVal int値\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putIntAttr(CharSequence attrName,\r
- int iVal)\r
- throws IOException{\r
- put(attrName).put('=').put('"').put(iVal).put('"');\r
- return this;\r
- }\r
-\r
- /**\r
- * float型属性値を出力する。\r
- * @param attrName 属性名\r
- * @param fVal float値\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putFloatAttr(CharSequence attrName,\r
- float fVal)\r
- throws IOException{\r
- put(attrName).put('=').put('"').put(fVal).put('"');\r
- return this;\r
- }\r
-\r
- /**\r
- * コメントの内容を出力する。\r
- * コメント中の\n記号出現に伴い、\r
- * あらかじめ指定された改行文字が出力される。\r
- * \n以外のコントロールコード各種、\r
- * 及び非BasicLatin文字はそのまま出力される。\r
- * 連続するハイフン(-)記号間には強制的にスペースが挿入される。\r
- * @param comment コメント内容\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putCommentContent(CharSequence comment)\r
- throws IOException{\r
- int length = comment.length();\r
-\r
- char prev = '\0';\r
- for(int pos = 0; pos < length; pos++){\r
- char ch = comment.charAt(pos);\r
- if(ch == '\n'){\r
- ln();\r
- prev = ch;\r
- continue;\r
- }\r
- if(prev == '-' && ch == '-') put(' ');\r
- put(ch);\r
- prev = ch;\r
- }\r
-\r
- return this;\r
- }\r
-\r
- /**\r
- * 1行コメントを出力する。\r
- * コメント中の\n記号出現に伴い、\r
- * あらかじめ指定された改行文字が出力される。\r
- * \n以外のコントロールコード各種、\r
- * 及び非BasicLatin文字はそのまま出力される。\r
- * 連続するハイフン(-)記号間には強制的にスペースが挿入される。\r
- * @param comment コメント内容\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putLineComment(CharSequence comment)\r
- throws IOException{\r
- put("<!--").put(' ');\r
- putCommentContent(comment);\r
- put(' ').put("-->");\r
- return this;\r
- }\r
-\r
- /**\r
- * ブロックコメントを出力する。\r
- * コメント中の\n記号出現に伴い、\r
- * あらかじめ指定された改行文字が出力される。\r
- * \n以外のコントロールコード各種、\r
- * 及び非BasicLatin文字はそのまま出力される。\r
- * 連続するハイフン(-)記号間には強制的にスペースが挿入される。\r
- * @param comment コメント内容\r
- * @return this本体\r
- * @throws IOException 出力エラー\r
- */\r
- public BasicXmlExporter putBlockComment(CharSequence comment)\r
- throws IOException{\r
- put("<!--").ln();\r
-\r
- putCommentContent(comment);\r
-\r
- int commentLength = comment.length();\r
- if(commentLength > 0){\r
- char lastCh = comment.charAt(commentLength - 1);\r
- if(lastCh != '\n') ln();\r
- }\r
-\r
- put("-->").ln();\r
-\r
- return this;\r
- }\r
-\r
-}\r
+/*
+ * basic xml exporter
+ *
+ * License : The MIT License
+ * Copyright(c) 2010 MikuToga Partners
+ */
+
+package jp.sourceforge.mikutoga.xml;
+
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import javax.xml.bind.DatatypeConverter;
+
+/**
+ * 各種XMLエクスポータの基本機能。
+ * UCS4は未サポート。
+ */
+public class BasicXmlExporter {
+
+ /** デフォルトエンコーディング。 */
+ private static final Charset CS_UTF8 = Charset.forName("UTF-8");
+
+ /** デフォルトの改行文字列。 */
+ private static final String LF = "\n"; // 0x0a
+ /** デフォルトのインデント単位。 */
+ private static final String DEFAULT_INDENT_UNIT = "\u0020\u0020";
+
+ private static final char[] HEXCHAR_TABLE = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F',
+ };
+
+ static{
+ assert HEXCHAR_TABLE.length == 16;
+ }
+
+
+ private final Appendable appendable;
+
+ private String newline = LF;
+ private String indentUnit = DEFAULT_INDENT_UNIT;
+
+ private int indentNest = 0;
+ private boolean basicLatinOnlyOut = true;
+
+
+ /**
+ * コンストラクタ。
+ * 文字エンコーディングはUTF-8が用いられる。
+ * @param stream 出力ストリーム
+ */
+ public BasicXmlExporter(OutputStream stream){
+ this(stream, CS_UTF8);
+ return;
+ }
+
+ /**
+ * コンストラクタ。
+ * @param stream 出力ストリーム
+ * @param charSet 文字エンコーディング指定
+ */
+ public BasicXmlExporter(OutputStream stream, Charset charSet){
+ this(
+ new BufferedWriter(
+ new OutputStreamWriter(stream, charSet)
+ )
+ );
+ return;
+ }
+
+ /**
+ * コンストラクタ。
+ * @param appendable 文字列出力
+ */
+ public BasicXmlExporter(Appendable appendable){
+ super();
+ this.appendable = appendable;
+ return;
+ }
+
+ /**
+ * ASCIIコード相当(UCS:Basic-Latin)の文字か否か判定する。
+ * @param ch 判定対象文字
+ * @return Basic-Latin文字ならtrue
+ */
+ public static boolean isBasicLatin(char ch){
+ if(ch <= 0x7f) return true;
+ return false;
+ }
+
+ /**
+ * 改行文字列を設定する。
+ * @param newLine 改行文字列
+ * @throws NullPointerException 引数がnull
+ */
+ public void setNewLine(String newLine) throws NullPointerException{
+ if(newLine == null) throw new NullPointerException();
+ this.newline = newLine;
+ return;
+ }
+
+ /**
+ * BasicLatin文字だけで出力するか設定する。
+ * BasicLatin以外の文字(≒日本語)をそのまま出力するか
+ * 文字参照で出力するかの設定が可能。
+ * コメント部中身は対象外。
+ * @param bool BasicLatin文字だけで出力するならtrue
+ */
+ public void setBasicLatinOnlyOut(boolean bool){
+ this.basicLatinOnlyOut = bool;
+ return;
+ }
+
+ /**
+ * BasicLatin文字だけを出力する状態か判定する。
+ * コメント部中身は対象外。
+ * @return BasicLatin文字だけで出力するならtrue
+ */
+ public boolean isBasicLatinOnlyOut(){
+ return this.basicLatinOnlyOut;
+ }
+
+ /**
+ * 改行文字列を設定する。
+ * デフォルトではLF(0x0a)\nが用いられる。
+ * @param seq 改行文字列。nullは空文字列""と解釈される。
+ */
+ public void setNewLine(CharSequence seq){
+ if(seq == null) this.newline = "";
+ else this.newline = seq.toString();
+ return;
+ }
+
+ /**
+ * インデント単位文字列を設定する。
+ * デフォルトでは空白2個。
+ * @param seq インデント単位文字列。nullは空文字列""と解釈される。
+ */
+ public void setIndentUnit(CharSequence seq){
+ if(seq == null) this.indentUnit = "";
+ else this.indentUnit = seq.toString();
+ }
+
+ /**
+ * 可能であれば出力をフラッシュする。
+ * @throws IOException 出力エラー
+ */
+ public void flush() throws IOException{
+ if(this.appendable instanceof Flushable){
+ ((Flushable)this.appendable).flush();
+ }
+ return;
+ }
+
+ /**
+ * 可能であれば出力をクローズする。
+ * @throws IOException 出力エラー
+ */
+ public void close() throws IOException{
+ if(this.appendable instanceof Closeable){
+ ((Closeable)this.appendable).close();
+ }
+ return;
+ }
+
+ /**
+ * 1文字出力する。
+ * @param ch 文字
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter put(char ch) throws IOException{
+ this.appendable.append(ch);
+ return this;
+ }
+
+ /**
+ * 文字列を出力する。
+ * @param seq 文字列
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter put(CharSequence seq) throws IOException{
+ this.appendable.append(seq);
+ return this;
+ }
+
+ /**
+ * int値を出力する。
+ * @param iVal int値
+ * @return this本体
+ * @throws IOException 出力エラー
+ * @see java.lang.Integer#toString(int)
+ */
+ public BasicXmlExporter put(int iVal) throws IOException{
+ String value = DatatypeConverter.printInt(iVal);
+ this.appendable.append(value);
+ return this;
+ }
+
+ /**
+ * float値を出力する。
+ * @param fVal float値
+ * @return this本体
+ * @throws IOException 出力エラー
+ * @see java.lang.Float#toString(float)
+ */
+ public BasicXmlExporter put(float fVal) throws IOException{
+ String value = DatatypeConverter.printFloat(fVal);
+ this.appendable.append(value);
+ return this;
+ }
+
+ /**
+ * 改行を出力する。
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter ln() throws IOException{
+ this.appendable.append(this.newline);
+ return this;
+ }
+
+ /**
+ * 改行を指定回数出力する。
+ * @param count 改行回数。0以下の場合は何も出力しない。
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter ln(int count) throws IOException{
+ for(int ct = 1; ct <= count; ct++){
+ this.appendable.append(this.newline);
+ }
+ return this;
+ }
+
+ /**
+ * インデントを出力する。
+ * インデント単位文字列をネストレベル回数分出力する。
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter ind() throws IOException{
+ for(int ct = 1; ct <= this.indentNest; ct++){
+ put(this.indentUnit);
+ }
+ return this;
+ }
+
+ /**
+ * インデントレベルを一段下げる。
+ */
+ public void pushNest(){
+ this.indentNest++;
+ return;
+ }
+
+ /**
+ * インデントレベルを一段上げる。
+ * インデントレベル0の状態をさらに上げようとした場合、何も起こらない。
+ */
+ public void popNest(){
+ this.indentNest--;
+ if(this.indentNest < 0) this.indentNest = 0;
+ return;
+ }
+
+ /**
+ * 指定された文字を16進2桁の文字参照形式で出力する。
+ * 2桁で出力できない場合は4桁で出力する。
+ * @param ch 文字
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putCharRef2Hex(char ch) throws IOException{
+ if(ch > 0xff) return putCharRef4Hex(ch);
+
+ char hex3 = HEXCHAR_TABLE[(ch >> 4) & 0x000f];
+ char hex4 = HEXCHAR_TABLE[(ch ) & 0x000f];
+
+ this.appendable.append("&#x");
+ this.appendable.append(hex3);
+ this.appendable.append(hex4);
+ this.appendable.append(';');
+
+ return this;
+ }
+
+ /**
+ * 指定された文字を16進4桁の文字参照形式で出力する。
+ * UCS4に伴うサロゲートペアは未サポート
+ * @param ch 文字
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putCharRef4Hex(char ch) throws IOException{
+ char hex1 = HEXCHAR_TABLE[(ch >> 12) & 0x000f];
+ char hex2 = HEXCHAR_TABLE[(ch >> 8) & 0x000f];
+ char hex3 = HEXCHAR_TABLE[(ch >> 4) & 0x000f];
+ char hex4 = HEXCHAR_TABLE[(ch ) & 0x000f];
+
+ this.appendable.append("&#x");
+ this.appendable.append(hex1);
+ this.appendable.append(hex2);
+ this.appendable.append(hex3);
+ this.appendable.append(hex4);
+ this.appendable.append(';');
+
+ return this;
+ }
+
+ /**
+ * 要素の中身および属性値中身を出力する。
+ * 必要に応じてXML定義済み実体文字が割り振られた文字、
+ * コントロールコード、および非BasicLatin文字がエスケープされる。
+ * @param content 内容
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putContent(CharSequence content)
+ throws IOException{
+ int length = content.length();
+
+ for(int pos = 0; pos < length; pos++){
+ char ch = content.charAt(pos);
+ if(Character.isISOControl(ch)){
+ putCharRef2Hex(ch);
+ }else if( ! isBasicLatin(ch) && isBasicLatinOnlyOut()){
+ putCharRef4Hex(ch);
+ }else{
+ switch(ch){
+ case '&': this.appendable.append("&"); break;
+ case '<': this.appendable.append("<"); break;
+ case '>': this.appendable.append(">"); break;
+ case '"': this.appendable.append("""); break;
+ case '\'': this.appendable.append("'"); break;
+ case '\u00a5': this.appendable.append('\u005c\u005c'); break;
+ default: this.appendable.append(ch); break;
+ }
+ }
+ }
+
+ return this;
+ }
+
+ /**
+ * 属性値を出力する。
+ * @param attrName 属性名
+ * @param content 属性内容
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putAttr(CharSequence attrName,
+ CharSequence content)
+ throws IOException{
+ put(attrName).put('=').put('"').putContent(content).put('"');
+ return this;
+ }
+
+ /**
+ * int型属性値を出力する。
+ * @param attrName 属性名
+ * @param iVal int値
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putIntAttr(CharSequence attrName,
+ int iVal)
+ throws IOException{
+ put(attrName).put('=').put('"').put(iVal).put('"');
+ return this;
+ }
+
+ /**
+ * float型属性値を出力する。
+ * @param attrName 属性名
+ * @param fVal float値
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putFloatAttr(CharSequence attrName,
+ float fVal)
+ throws IOException{
+ put(attrName).put('=').put('"').put(fVal).put('"');
+ return this;
+ }
+
+ /**
+ * コメントの内容を出力する。
+ * コメント中の\n記号出現に伴い、
+ * あらかじめ指定された改行文字が出力される。
+ * \n以外のコントロールコード各種、
+ * 及び非BasicLatin文字はそのまま出力される。
+ * 連続するハイフン(-)記号間には強制的にスペースが挿入される。
+ * @param comment コメント内容
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putCommentContent(CharSequence comment)
+ throws IOException{
+ int length = comment.length();
+
+ char prev = '\0';
+ for(int pos = 0; pos < length; pos++){
+ char ch = comment.charAt(pos);
+ if(ch == '\n'){
+ ln();
+ prev = ch;
+ continue;
+ }
+ if(prev == '-' && ch == '-') put(' ');
+ put(ch);
+ prev = ch;
+ }
+
+ return this;
+ }
+
+ /**
+ * 1行コメントを出力する。
+ * コメント中の\n記号出現に伴い、
+ * あらかじめ指定された改行文字が出力される。
+ * \n以外のコントロールコード各種、
+ * 及び非BasicLatin文字はそのまま出力される。
+ * 連続するハイフン(-)記号間には強制的にスペースが挿入される。
+ * @param comment コメント内容
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putLineComment(CharSequence comment)
+ throws IOException{
+ put("<!--").put(' ');
+ putCommentContent(comment);
+ put(' ').put("-->");
+ return this;
+ }
+
+ /**
+ * ブロックコメントを出力する。
+ * コメント中の\n記号出現に伴い、
+ * あらかじめ指定された改行文字が出力される。
+ * \n以外のコントロールコード各種、
+ * 及び非BasicLatin文字はそのまま出力される。
+ * 連続するハイフン(-)記号間には強制的にスペースが挿入される。
+ * @param comment コメント内容
+ * @return this本体
+ * @throws IOException 出力エラー
+ */
+ public BasicXmlExporter putBlockComment(CharSequence comment)
+ throws IOException{
+ put("<!--").ln();
+
+ putCommentContent(comment);
+
+ int commentLength = comment.length();
+ if(commentLength > 0){
+ char lastCh = comment.charAt(commentLength - 1);
+ if(lastCh != '\n') ln();
+ }
+
+ put("-->").ln();
+
+ return this;
+ }
+
+}