Created
March 20, 2011 19:28
-
-
Save kxbmap/878580 to your computer and use it in GitHub Desktop.
ポリモーフィズムで再帰的なXMLを生成する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.kvxml2 | |
import _root_.scala.xml.{Elem, MetaData, Node, NodeSeq, Null, Text, TopScope, UnprefixedAttribute} | |
sealed abstract class Value { | |
def nodes: NodeSeq | |
} | |
case class StringValue(str: String) extends Value { | |
def nodes = Text(str) | |
} | |
case class ValueSeq(seq: Seq[Value]) extends Value { | |
def nodes = seq flatMap (_.nodes) | |
} | |
case class KeyValue(key: String, attributes: Map[String, String], value: Value) extends Value { | |
def this(key: String, value: Value) = this(key, Map.empty, value) | |
def xml: Node = Elem(null, key, meta, TopScope, value.nodes: _*) | |
def meta = ((Null: MetaData) /: attributes){ (meta, attr) => | |
new UnprefixedAttribute(attr._1, attr._2, meta) | |
} | |
def nodes = xml | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.kvxml2 | |
import org.specs2._ | |
import scala.xml.PrettyPrinter | |
class KeyValueSpec extends Specification { def is = | |
"ポリモーフィズム版KeyValueのテスト" ^ | |
"XMLリテラルと一致する" ! S.example1 ^ | |
"PrettyPrinterで生成したStringが一致する" ! S.example2 ^ | |
"改行とインデント込みでXMLリテラルに一致する" ! S.example3 ^ | |
end | |
object S { | |
implicit def string2value(str: String): Value = StringValue(str) | |
implicit def seq2value(seq: Seq[Value]): Value = ValueSeq(seq) | |
val kv = | |
KeyValue("langs", Map("type" -> "current"), Seq( | |
new KeyValue("key1", "value1"), | |
new KeyValue("key2", "value2"), | |
new KeyValue("key3", Seq( | |
new KeyValue("key3-1", "value3-1"), | |
new KeyValue("key3-2", "value3-2") | |
)) | |
)) | |
def example1 = kv.xml must_== | |
<langs type="current"><key1>value1</key1><key2>value2</key2><key3><key3-1>value3-1</key3-1><key3-2>value3-2</key3-2></key3></langs> | |
def example2 = { | |
val expect = """<langs type="current"> | |
| <key1>value1</key1> | |
| <key2>value2</key2> | |
| <key3> | |
| <key3-1>value3-1</key3-1> | |
| <key3-2>value3-2</key3-2> | |
| </key3> | |
|</langs>""".stripMargin | |
new PrettyPrinter(80, 2).format(kv.xml) must_== expect | |
} | |
val kv2 = { | |
val nl = "\n" | |
val indent = " " | |
KeyValue("langs", Map("type" -> "current"), Seq[Value]( | |
nl + indent, | |
new KeyValue("key1", "value1"), | |
nl + indent, | |
new KeyValue("key2", "value2"), | |
nl + indent, | |
new KeyValue("key3", Seq[Value]( | |
nl + indent * 2, | |
new KeyValue("key3-1", "value3-1"), | |
nl + indent * 2, | |
new KeyValue("key3-2", "value3-2"), | |
nl + indent | |
)), | |
nl | |
)) | |
} | |
def example3 = kv2.xml must_== | |
<langs type="current"> | |
<key1>value1</key1> | |
<key2>value2</key2> | |
<key3> | |
<key3-1>value3-1</key3-1> | |
<key3-2>value3-2</key3-2> | |
</key3> | |
</langs> | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment