ざっくりと試してみたSimpleライブラリ。
いろいろと気になる点もあったので、ざくっと検証してみる。の続き。
要素名や属性名は「JavaBean標準」固定なのか
Lureクラスなら"lure"という風になるということだが、それ以外の形式は不可なのか。
そこで、SimpleライブラリのJavaDocとチュートリアルを見てみると、CamelCaseStyleやHyphenStyleというのが利用可能らしい。ということで次の検証コードを作成。
import java.io.File; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import org.simpleframework.xml.stream.CamelCaseStyle; import org.simpleframework.xml.stream.Format; import org.simpleframework.xml.stream.HyphenStyle; public class Main { /** * @param args */ public static void main(String[] args) { System.out.println("=== new Persister() ==="); try { Serializer serializer = new Persister(); TestPojo testPojo = newTestPojo(); File result = new File("data/main-default.xml"); System.out.println(" " + result); serializer.write(testPojo, result); } catch (Exception e) { e.printStackTrace(System.out); } System.out.println("=== new Persister(new Format(new CamelCaseStyle())) ==="); try { Serializer serializer = new Persister(new Format(new CamelCaseStyle())); TestPojo testPojo = newTestPojo(); File result = new File("data/main-CamelCase.xml"); System.out.println(" " + result); serializer.write(testPojo, result); } catch (Exception e) { e.printStackTrace(System.out); } System.out.println("=== new Persister(new Format(new CamelCaseStyle(false, true))) ==="); try { Serializer serializer = new Persister(new Format(new CamelCaseStyle(false, true))); TestPojo testPojo = newTestPojo(); File result = new File("data/main-CamelCaseR.xml"); System.out.println(" " + result); serializer.write(testPojo, result); } catch (Exception e) { e.printStackTrace(System.out); } System.out.println("=== new Persister(new Format(new HyphenStyle())) ==="); try { Serializer serializer = new Persister(new Format(new HyphenStyle())); TestPojo testPojo = newTestPojo(); File result = new File("data/main-Hyphen.xml"); System.out.println(" " + result); serializer.write(testPojo, result); } catch (Exception e) { e.printStackTrace(System.out); } String[] styles = { "default", "CamelCase", "CamelCaseR", "Hyphen", }; System.out.println("=== new Persister() ==="); for (String style : styles) { System.out.println(" === " + style + " ==="); try { Serializer serializer = new Persister(); File source = new File("data/main-" + style + ".xml"); System.out.println(" " + source); TestPojo testPojo = serializer.read(TestPojo.class, source); dumpTestPojo(testPojo); } catch (Exception e) { e.printStackTrace(System.out); } } System.out.println("=== new Persister(new Format(new CamelCaseStyle())) ==="); for (String style : styles) { System.out.println(" === " + style + " ==="); try { Serializer serializer = new Persister(new Format(new CamelCaseStyle())); File source = new File("data/main-" + style + ".xml"); System.out.println(" " + source); TestPojo testPojo = serializer.read(TestPojo.class, source); dumpTestPojo(testPojo); } catch (Exception e) { e.printStackTrace(System.out); } } System.out.println("=== new Persister(new Format(new CamelCaseStyle(false, true))) ==="); for (String style : styles) { System.out.println(" === " + style + " ==="); try { Serializer serializer = new Persister(new Format(new CamelCaseStyle(false, true))); File source = new File("data/main-" + style + ".xml"); System.out.println(" " + source); TestPojo testPojo = serializer.read(TestPojo.class, source); dumpTestPojo(testPojo); } catch (Exception e) { e.printStackTrace(System.out); } } System.out.println("=== new Persister(new Format(new HyphenStyle())) ==="); for (String style : styles) { System.out.println(" === " + style + " ==="); try { Serializer serializer = new Persister(new Format(new HyphenStyle())); File source = new File("data/main-" + style + ".xml"); System.out.println(" " + source); TestPojo testPojo = serializer.read(TestPojo.class, source); dumpTestPojo(testPojo); } catch (Exception e) { e.printStackTrace(System.out); } } } private static TestPojo newTestPojo() { TestPojo testPojo = new TestPojo(); testPojo.setFirstElement("firstElement"); testPojo.setSecondElement("SecondElement"); testPojo.setThirdElement("THIRDELEMENT"); testPojo.setFourthElement("fourth_element"); testPojo.setFifthElement("Fifth_Element"); testPojo.setSixthElement("SIXTH_ELEMENT"); testPojo.setFirstAttribute("firstAttribute"); testPojo.setSecondAttribute("SecondAttribute"); testPojo.setThirdAttribute("THIRDATTRIBUTE"); testPojo.setFourthAttribute("fourth_attribute"); testPojo.setFifthAttribute("Fifth_Attribute"); testPojo.setSixthAttribute("SIXTH_ATTRIBUTE"); return testPojo; } private static void dumpTestPojo(TestPojo testPojo) { System.out.println(" firstElement: " + testPojo.getFirstElement()); System.out.println(" secondElement: " + testPojo.getSecondElement()); System.out.println(" thirdElement: " + testPojo.getThirdElement()); System.out.println(" fourthElement: " + testPojo.getFourthElement()); System.out.println(" fifthElement: " + testPojo.getFifthElement()); System.out.println(" firstAttribute: " + testPojo.getFirstAttribute()); System.out.println(" secondAttribute: " + testPojo.getSecondAttribute()); System.out.println(" thirdAttribute: " + testPojo.getThirdAttribute()); System.out.println(" fourthAttribute: " + testPojo.getFourthAttribute()); System.out.println(" fifthAttribute: " + testPojo.getFifthAttribute()); } }
Persisterクラスのコンストラクタに渡すFormatオブジェクトには、Styleオブジェクトを渡すことができる。Styleを何も渡さなければ「JavaBean標準」になるし、CamelCaseStyleオブジェクトやHyphenStyleオブジェクトを渡せば指定したとおりの動作になる。また、CamelCaseStyleでは要素名と属性名のそれぞれに対して先頭の文字を大文字にするか小文字にするかをコンストラクタの引数によって設定することができる。引数なしのコンストラクタでは要素名は大文字、属性名は小文字ということなので、「new CamelCaseStyle(false, true)」を使って要素名が小文字、属性名が大文字のケースも実行してみる。
TestPojoクラスは次のとおり。
import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; @Root public class TestPojo { @Element private String firstElement; @Element private String SecondElement; @Element private String THIRDELEMENT; @Element private String fourth_element; @Element private String Fifth_Element; @Element private String SIXTH_ELEMENT; @Attribute private String firstAttribute; @Attribute private String SecondAttribute; @Attribute private String THIRDATTRIBUTE; @Attribute private String fourth_attribute; @Attribute private String Fifth_Attribute; @Attribute private String SIXTH_ATTRIBUTE; public String getFirstElement() { return firstElement; } public void setFirstElement(String firstElement) { this.firstElement = firstElement; } public String getSecondElement() { return SecondElement; } public void setSecondElement(String secondElement) { this.SecondElement = secondElement; } public String getThirdElement() { return THIRDELEMENT; } public void setThirdElement(String thirdElement) { this.THIRDELEMENT = thirdElement; } public String getFourthElement() { return fourth_element; } public void setFourthElement(String fourthElement) { this.fourth_element = fourthElement; } public String getFifthElement() { return Fifth_Element; } public void setFifthElement(String fifthElement) { this.Fifth_Element = fifthElement; } public String getSixthElement() { return SIXTH_ELEMENT; } public void setSixthElement(String sixthElement) { this.SIXTH_ELEMENT = sixthElement; } public String getFirstAttribute() { return firstAttribute; } public void setFirstAttribute(String firstAttribute) { this.firstAttribute = firstAttribute; } public String getSecondAttribute() { return SecondAttribute; } public void setSecondAttribute(String secondAttribute) { this.SecondAttribute = secondAttribute; } public String getThirdAttribute() { return THIRDATTRIBUTE; } public void setThirdAttribute(String thirdAttribute) { this.THIRDATTRIBUTE = thirdAttribute; } public String getFourthAttribute() { return fourth_attribute; } public void setFourthAttribute(String fourthAttribute) { this.fourth_attribute = fourthAttribute; } public String getFifthAttribute() { return Fifth_Attribute; } public void setFifthAttribute(String fifthAttribute) { this.Fifth_Attribute = fifthAttribute; } public String getSixthAttribute() { return SIXTH_ATTRIBUTE; } public void setSixthAttribute(String sixthAttribute) { this.SIXTH_ATTRIBUTE = sixthAttribute; } }
それぞれのスタイルでどのような変換が行われるのかを見るために、6つのパターンのフィールド名を持っている。中にはインスタンスフィールド名としては不適切だ、というものも含まれている。
これを実行してみると、次のファイルが生成される。
その内容そのものはここでは割愛するとして、それぞれのスタイルで要素名、属性名がどんな風になったのかを表にしてみた。
= | =default | =CamelCase(true) | =CamelCase(false) | =Hyphen |
クラス名(TestPojo) | testPojo | TestPojo | testPojo | test-pojo |
firstElement | firstElement | FirstElement | firstElement | first-element |
SecondElement | SecondElement | SecondElement | SecondElement | second-element |
THIRDELEMENT | THIRDELEMENT | THIRDELEMENT | THIRDELEMENT | THIRDELEMENT |
fourth_element | fourth_element | FourthElement | fourthelement | fourth-element |
Fifth_Element | Fifth_Element | FifthElement | FifthElement | fifth-element |
SIXTH_ELEMENT | SIXTH_ELEMENT | SIXTHELEMENT | SIXTHELEMENT | SIXT-h-ELEMENT |
firstAttribute | firstAttribute | FirstAttribute | firstAttribute | first-attribute |
SecondAttribute | SecondAttribute | SecondAttribute | SecondAttribute | second-attribute |
THIRDATTRIBUTE | THIRDATTRIBUTE | THIRDATTRIBUTE | THIRDATTRIBUTE | THIRDATTRIBUTE |
fourth_attribute | fourth_attribute | FourthAttribute | fourthattribute | fourth-attribute |
Fifth_Attribute | Fifth_Attribute | FifthAttribute | FifthAttribute | fifth-attribute |
SIXTH_ATTRIBUTE | SIXTH_ATTRIBUTE | SIXTHATTRIBUTE | SIXTHATTRIBUTE | SIXT-h-ATTRIBUTE |
"SIXTH_ELEMENT"、"SIXTH_ATTRIBUTE"だけが予想の範囲外の動作。まぁ、インスタンスフィールド名としては使用しないパターンだからいいんだけど。
また、実行結果のコンソール出力は次のような感じ。
=== new Persister() === data\main-default.xml === new Persister(new Format(new CamelCaseStyle())) === data\main-CamelCase.xml === new Persister(new Format(new CamelCaseStyle(false, true))) === data\main-CamelCaseR.xml === new Persister(new Format(new CamelCaseStyle(true, false))) === data\main-CamelCase2.xml === new Persister(new Format(new HyphenStyle())) === data\main-Hyphen.xml === new Persister() === === default === data\main-default.xml firstElement: firstElement secondElement: SecondElement thirdElement: THIRDELEMENT fourthElement: fourth_element fifthElement: Fifth_Element firstAttribute: firstAttribute secondAttribute: SecondAttribute thirdAttribute: THIRDATTRIBUTE fourthAttribute: fourth_attribute fifthAttribute: Fifth_Attribute === CamelCase === data\main-CamelCase.xml org.simpleframework.xml.core.AttributeException: Attribute 'fourthattribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === CamelCaseR === data\main-CamelCaseR.xml org.simpleframework.xml.core.AttributeException: Attribute 'FirstAttribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === Hyphen === data\main-Hyphen.xml org.simpleframework.xml.core.AttributeException: Attribute 'first-attribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === new Persister(new Format(new CamelCaseStyle())) === === default === data\main-default.xml org.simpleframework.xml.core.AttributeException: Attribute 'fourth_attribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === CamelCase === data\main-CamelCase.xml firstElement: firstElement secondElement: SecondElement thirdElement: THIRDELEMENT fourthElement: fourth_element fifthElement: Fifth_Element firstAttribute: firstAttribute secondAttribute: SecondAttribute thirdAttribute: THIRDATTRIBUTE fourthAttribute: fourth_attribute fifthAttribute: Fifth_Attribute === CamelCaseR === data\main-CamelCaseR.xml org.simpleframework.xml.core.AttributeException: Attribute 'FirstAttribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === Hyphen === data\main-Hyphen.xml org.simpleframework.xml.core.AttributeException: Attribute 'first-attribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === new Persister(new Format(new CamelCaseStyle(false, true))) === === default === data\main-default.xml org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === CamelCase === data\main-CamelCase.xml org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === CamelCaseR === data\main-CamelCaseR.xml firstElement: firstElement secondElement: SecondElement thirdElement: THIRDELEMENT fourthElement: fourth_element fifthElement: Fifth_Element firstAttribute: firstAttribute secondAttribute: SecondAttribute thirdAttribute: THIRDATTRIBUTE fourthAttribute: fourth_attribute fifthAttribute: Fifth_Attribute === Hyphen === data\main-Hyphen.xml org.simpleframework.xml.core.AttributeException: Attribute 'first-attribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === new Persister(new Format(new HyphenStyle())) === === default === data\main-default.xml org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === CamelCase === data\main-CamelCase.xml org.simpleframework.xml.core.AttributeException: Attribute 'firstAttribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === CamelCaseR === data\main-CamelCaseR.xml org.simpleframework.xml.core.AttributeException: Attribute 'FirstAttribute' does not exist at line -1 at org.simpleframework.xml.core.Composite.readAttribute(Composite.java:511) : === Hyphen === data\main-Hyphen.xml firstElement: firstElement secondElement: SecondElement thirdElement: THIRDELEMENT fourthElement: fourth_element fifthElement: Fifth_Element firstAttribute: firstAttribute secondAttribute: SecondAttribute thirdAttribute: THIRDATTRIBUTE fourthAttribute: fourth_attribute fifthAttribute: Fifth_Attribute
見るとわかるとおり、write時のスタイルとread時のスタイルは同じでないと読み込みに失敗する。まぁ、これはどんなライブラリ/ツールを使ってもそうだろう。想定している要素が存在しなければ当然エラーにすべき。
ライブラリで提供されていないケースを要素名や属性名に対して適用したい場合は独自のスタイル(Styleインタフェースの実装)を作ればいいので、拡張性はあるといえる。