S-JIS[2011-02-11/2013-09-18] �ύX����

Scala XML

Scala��XML�𑀍삷���B


XML���e����

Scala�ł�XML���v���O�������ɒ��ڏ������Ƃ��o����iXML���e�����j�B
�܂��A�g���ʂł��������u���b�N����邱�Ƃɂ��AXML���e�����̊O�̕ϐ��≉�Z���L�q���邱�Ƃ��o����B

Scala ���e ���l
val x1 = <sample>hoge</sample>
val x2 =
<sample>
  <zzz>test</zzz>
  <foo/>
</sample>
x1: scala.xml.Elem = <sample>hoge</sample>

x2: scala.xml.Elem =
<sample>
  <zzz>test</zzz>
  <foo></foo>
</sample>
�u<�^�O/>�v�Ƃ����`���Ŏw�肵���^�O��
�u<�^�O></�^�O>�v�Ƃ����`�ŕێ������悤���B
val x3 = <sample>
  <!-- comment -->
</sample>
x3: scala.xml.Elem =
<sample>
  <!-- comment -->
</sample>
�R�����g���w��”\�B
val name = "world"

val x = <s>hello,{name}</s>
val n = <s>{ 123 + 456 }</s>
x: scala.xml.Elem = <s>hello,world</s>

n: scala.xml.Elem = <s>579</s>
�g���ʂň͂񂾃u���b�N��Scala�̎��Ƃ��ĕ]���i���Z�j����A
���̈ʒu�ɖ��ߍ��܂��B
�iString��format����Ɏg���邩���H�j
���̃u���b�N���ł͉��s�ł��Ȃ��B
val xl = <list>
{ List(1,2,3) }
</list>
val xm = <map>
{ Map("a"->123, "b"->456) }
</map>
xl: scala.xml.Elem =
<list>
123
</list>

xm: scala.xml.Elem =
<map>
(a,123)(b,456)
</map>
List��Map��n���Ƃ��̓��e�̕�����ɂȂ�悤����
toString()�̖߂�l�Ƃ�mkString()�Ƃ��قȂ�̂ŁA
�ǂ��������[���ŕϊ������̂���B
val xx = <t1>
{ <t2>zzz</t2> }
</t1>
val xf = <t1>
{ for(i <- 1 to 3) yield <t>{i}</t> }
</t1>
xx: scala.xml.Elem =
<t1>
<t2>zzz</t2>
</t1>

xf: scala.xml.Elem =
<t1>
<t>1</t><t>2</t><t>3</t>
</t1>
�u���b�N���ł����XML���e�������w�肷�鎖���o����悤���B
�i���[�v���ʼn��s������ɂ͂ǂ������炢���񂾂낤�H�j
val e = <s>
&quot;foo&amp;bar&quot;
</s>
�~ <s>"foo&bar"</s>
e: scala.xml.Elem =
<s>
&quot;foo&amp;bar&quot;
</s>
�召�L����u&�v���G�X�P�[�v�������́i���̎Q�Ɓj���w�肷��K�v������B
val e = <escape>
{ """<>&"'""" }
</escape>
e: scala.xml.Elem =
<escape>
&lt;&gt;&amp;&quot;'
</escape>
�g���ʂ̃u���b�N���̕�����ɑ召�L�����������
�����I���G�X�P�[�v�����B
val c1 = <s><![CDATA[<p>]]></s>
val c2 = <s><![CDATA[{"<p>"}]]></s>
c1: scala.xml.Elem = <s>&lt;p&gt;</s>

c: scala.xml.Elem = <s>{&quot;&lt;p&gt;&quot;}</s>
CDATA�Z�N�V�����������Ǝg����B
�g���ʃu���b�N��CDATA�Z�N�V�����̈ꕔ�Ƃ݂Ȃ���AScala�̎��͏����Ȃ��B
val a1 = <tag attr="123" />
val a2 = <tag attr='456' />
a1: scala.xml.Elem = <tag attr="123"></tag>

a2: scala.xml.Elem = <tag attr="456"></tag>
�����l�̓_�u���N�H�[�e�[�V�����ł��V���O���N�H�[�e�[�V�����ł��w��”\�B
�i�͂܂Ȃ��̂�XML�̋K��ᔽ�Ȃ̂ŃR���p�C���G���[�j
val a = <tag attr={ "123" } />
�~ <tag attr={ 123 } />
�~ <tag { "attr" } = "123" />
�~ <tag { "attr=123" } />
a: scala.xml.Elem = <tag attr="123"></tag> �����l�ɂ��g���ʃu���b�N���w��”\�B
���������̓��e��String�łȂ��ƑʖڂȂ悤���B
�i�Ⴆ�ΐ��l���w�肷��ƃR���p�C���G���[�ɂȂ�j
�܂��A���������u���b�N�ɂ��鎖�͏o���Ȃ��B
�i�����S�̂������ɂ���ďo������o���Ȃ�������Ƃ������Ƃ͏o���Ȃ��j

������XML

������iString�j����XML�ɕϊ�����ɂ�scala.xml.XML�I�u�W�F�N�g���g�p����B

scala> val s = """<sample>
     |   <hoge>zzz</hoge>
     | </sample>
     | """
s: java.lang.String =
<sample>
  <hoge>zzz</hoge>
</sample>

scala> import scala.xml.XML

scala> val xml = XML.loadString(s)
xml: scala.xml.Elem =
<sample>
  <hoge>zzz</hoge>
</sample>

XML��������

XML���當����iString�j���擾������@�B

��Ƃ��āA�ȉ��̗l��XML��������̂Ƃ���B

val xml =
<html>
<head>
  <title>�^�C�g��</title>  <!-- ���� -->
</head>
<body>
<p align='center'>�e�X�g<br/>�ł��B</p>
</body>
</html>
Scala ���e ���l
val s = xml.toString()
s: String =
<html>
<head>
  <title>�^�C�g��</title>  <!-- ���� -->
</head>
<body>
<p align="center">�e�X�g<br></br>�ł��B</p>
</body>
</html>
toString()���g���ƁA��{�I�ɐ��������ۂ�XML���擾�ł���B
�‚܂�X�y�[�X���̃C���f���g�͂��̂܂܎c��B
�������A�����l�̓_�u���N�H�[�e�[�V�����ň͂܂�邵�A
�u<�^�O/>�v�́u<�^�O></�^�O>�v�Ƃ����`�ɂȂ�B
val s = xml.text
s: String =


  �^�C�g��


�e�X�g�ł��B

text���g���ƁA�^�O���������e�L�X�g�i������j�������擾�ł���B
val s = xml.label
s: String = html
label�ŗv�f�����擾�ł���B
import scala.xml.PrettyPrinter
val pp = new PrettyPrinter(40, 2)
val s = pp.format(xml)
s: String =
<html>
  <head>
    <title>�^�C�g��</title>
    <!-- ���� -->
  </head>
  <body>
    <p align="center">
      �e�X�g
      <br></br>
      �ł��B
    </p>
  </body>
</html>
�C���f���g�𐮌`����ɂ�PrettyPrinter�N���X���g����B
�R���X�g���N�^�[�̑�2�����ŃC���f���g�̒P�ʌ������w�肷��B
��1������width�����������A�ǂ��������ʂ�����̂��s���B
import scala.xml.Xhtml
val s = Xhtml.toXhtml(xml)
s: String =
<html>
<head>
  <title>�^�C�g��</title>  <!-- ���� -->
</head>
<body>
<p align="center">�e�X�g<br />�ł��B</p>
</body>
</html>
XHTML�X�^�C���Ő��`����ɂ�Xhtml�I�u�W�F�N�g���g����B
��{�I�ɂ�toString()�ł̏o�͂Ɠ����悤�����A
br�^�O��1�‚��������o�͂���Ȃ��B

XML�t�@�C������̓ǂݍ��݁E�t�@�C���ւ̕ۑ�

scala.xml.XML�I�u�W�F�N�g�Ƀt�@�C���Ƃ̓ǂݏ������s�����\�b�h���p�ӂ���Ă���B

XML.load()��InputSource��InputStream�EReader����XML�C���X�^���X�𐶐����邱�Ƃ��o����B
XML.loadFile()�Ńt�@�C�������w�肵��XML�t�@�C����ǂݍ��ނ��Ƃ��o����B
XML.loadXML()��SAXParser���w�肷�邱�Ƃ��o����B

XML.save()�Ńt�@�C���֕ۑ��AXML.write()��Writer�֏����o�����Ƃ��o����B


save

XML�I�u�W�F�N�g��XML�t�@�C���ɕۑ������B[2013-09-18]

import scala.xml.XML
import scala.xml.dtd.DocType
import scala.xml.dtd.PublicID
  val html = <html><head><title>zzz</title></head><body>zzz</body></html>
  val doctype = DocType("html", PublicID("-//W3C//DTD HTML 4.01 Transitional//EN", null), Nil)
  XML.save("test.html", html, "UTF-8", false, doctype)

loadFile

XML�I�u�W�F�N�g���g����XML�t�@�C����ǂݍ��ޗ�B[2012-04-14]

import scala.xml.XML
  val f = new File("hoge.xml")
  val xml = XML.loadFile(f)

���������̕��@���ƁA���[�g�G�������g�i��ԊO���̗v�f�j�������Ȃ��B
�‚܂�AXML�����������Ȃǂ���邱�Ƃ��o���Ȃ��B

loadFile()�̒��̃p�[�T�[�ł͓��R�������߂��ǂݍ���ł���̂����AloadFile()�������Ԃ��悤�ɂȂ��Ă��Ȃ��B
XML�I�u�W�F�N�g��XMLLoader�g���C�g���p�����Ă���A�������߂͂��̒���adapter�ŕێ����Ă���B
���������āA������XMLLoader���p�������N���X�����Aadapter������o����悤�ɂ���΂����B

adapter��def�i���\�b�h�j�Ȃ̂ŁA�Ăяo�����тɐV�����C���X�^���X���Ԃ��Ă���B���������āA��x�����C���X�^���X������āA��͂����Ԃ��悤�ɂ���B
���̂��߁Adef��val�ŃI�[�o�[���C�h����B

import scala.xml.Elem
import scala.xml.factory.XMLLoader
  val loader = new XMLLoader[Elem] {
    override lazy val adapter = super.adapter
  }
  val xml = loader.loadFile(f)
  val pis = loader.adapter.hStack.toSeq.collect{ case p: ProcInstr => p }.reverse //�������߈ꗗ

�R�����g�͂���ɕʂ̎�i�łȂ��Ǝ��Ȃ��B
XMLLoader�̒���parser��LexicalHandler�Ƃ����n���h���[��o�^����K�v������B
XML�h�L�������g�̒��ɃR�����g�����‚���Ƃ��̃n���h���[���Ă΂��̂ŁA���̂Ƃ���adapter.hStack�ɃR�����g�I�u�W�F�N�g��lj����Ă��B

import org.xml.sax.ext.DefaultHandler2 //LexicalHandler�C���^�[�t�F�[�X�����������N���X

import scala.xml.Comment
  val loader = new XMLLoader[Elem] {
    override lazy val adapter = super.adapter

    override def parser = {
      val p = super.parser
      p.setProperty("http://xml.org/sax/properties/lexical-handler", new DefaultHandler2 {
        override def comment(ch: Array[Char], start: Int, length: Int): Unit = {
          val s = String.valueOf(ch, start, length)
          val c = Comment(s)
          adapter.hStack.push(c)
        }
      })
      p
    }
  }

��LexicalHandler��o�^����ׂ̃v���p�e�B�[���ɂ‚��ẮASAXParserImpl.JAXPSAXParser#setProperty()���Q��


ConstructingParser

ConstructingParser���g����XML���p�[�X������@������B[2012-04-14]
��������g���ƁAXML�錾�ɏ�����Ă���G���R�[�f�B���O��DTD�i<!DOCTYPE�`>�j�A���������i<?�`?>�j��R�����g �i<!--�`-->�j���擾���邱�Ƃ��o����B

import scala.xml.parsing.ConstructingParser
import scala.xml.Elem
import scala.xml.Comment
import scala.xml.ProcInstr
  val f = new File("hoge.xml")
  val doc = ConstructingParser.fromFile(f, false).document()

  println(doc.encoding)	//�G���R�[�f�B���O
  println(doc.dtd)	//DTD

  val xml = doc.docElem	//���[�g�v�f
  println(xml)

  val seq = doc.children	//�m�[�h�ꗗ�B�������߂⃋�[�g�v�f�Ȃ�
  seq.foreach {
    _ match {
      case e: Elem      => println("�v�f�ielement�j " + e)
      case p: ProcInstr => println("�������߁iprocessing instruction�j " + p)
      case c: Comment   => println("�R�����g�icomment�j " + c)
      case n            => println("���̑��inode�j " + n.getClass())
    }
  }

fromFile()�̑�2����preserveWS�ɂ́A�󔒕����iwhite space�j��ێ����邩�ǂ������w�肷��B
true�ɂ��Ă����ƁA�^�O�ƃ^�O�̊Ԃ̃^�u����s�Ƃ����e�L�X�g�Ƃ��ăm�[�h�ꗗ�ɓ���B


�������A�G���R�[�f�B���O�͎��s�‹��ɂ���Č��܂��Ă��܂��͗l�B�i�t�@�C�����̃G���R�[�f�B���O�������F�����Ă���Ȃ��j
���ߑł��ł����Ȃ�A�ȉ��̂悤�ɂ��Ďw��ł���B

  val f = new File("hoge.xml")
  val s = Source.fromFile(f, "UTF-8")
  val doc = ConstructingParser.fromSource(s, false).document()

XML�̒T��

XML���̗v�f�⑮�����擾������@�B

��Ƃ��āA�ȉ��̗l��XML��������̂Ƃ���B

val xml =
<html>
<body>
<h1>test</h1>
<ul>
  <li>hoge</li>
  <li>fuge</li>
  <li><a href="url">hage</a></li>
</ul>
</body>
</html>
Scala ���e ���l
val b = xml \ "body"
b: scala.xml.NodeSeq =
NodeSeq(<body>
<h1>test</h1>
<ul>
  <li>hoge</li>
  <li>fuge</li>
  <li><a href="url">hage</a></li>
</ul>
</body>)
\���\�b�h�ŁA�v�f�����w�肵��XML�v�f���擾�ł���B

�Ԃ�l��NodeSeq�A�‚܂蕡���̗v�f�����邱�Ƃ�����B

1�‚����‚���Ȃ������ꍇ�͋��NodeSeq���Ԃ�B
val l = xml \ "body" \ "ul" \ "li"
l: scala.xml.NodeSeq = NodeSeq(<li>hoge</li>, <li>fuge</li>, <li><a href="url">hage</a></li>)
val e = xml \ "body" \ "a"
e: scala.xml.NodeSeq = NodeSeq()
val l = xml \\ "li"
l: scala.xml.NodeSeq = NodeSeq(<li>hoge</li>, <li>fuge</li>, <li><a href="url">hage</a></li>) \\���\�b�h�ŁA�Ԃ̗v�f���΂���XML�v�f���擾���邱�Ƃ��o����B
for (li <- xml \\ "li") println(li)
<li>hoge</li>
<li>fuge</li>
<li><a href="url">hage</a></li>
val h = xml \\ "a" \ "@href"
h: scala.xml.NodeSeq = url �擪�Ɂu@�v��t����ƁA�v�f���łȂ��������̎w��ƂȂ�B
val ns = xml match {
  case <html>{ n @ _* }</html> => n
}
ns: Seq[scala.xml.Node] =
ArrayBuffer(
, <body>
<h1>test</h1>
<ul>
  <li>hoge</li>
  <li>fuge</li>
  <li><a href="url">hage</a></li>
</ul>
</body>,
)
match���ɂ��p�^�[���}�b�`���s�����Ƃ��o����B
(xml \ "body")(0) match {
  case <body>{ ns @ _* }</body> =>
    for (n <- ns) {
      n match {
        case <h1>{ h      }</h1> => println("h1")
        case <ul>{ u @ _* }</ul> => println("ul")
        case _ =>
      }
    }
}
h1
ul
for (bs <- xml \ "body") {
  for (h @ <h1>{ _ }</h1> <- bs.child) {
    println(h)
  }
}

�@

<h1>test</h1> for���ɂ��p�^�[���}�b�`��
���v����v�f�����擾���邱�Ƃ��o����B

�u�ϐ��� @ �p�^�[���v�́A�p�^�[���ɍ��v�����ꍇ��
���̑S�̂�ϐ��ɑ������B
�p�^�[�����ɕϐ�������Ƃ���
���̕��������ϐ��ɑ������B
for (bs <- xml \ "body") {
  for (<h1>{ h }</h1> <- bs.child) {
    println(h)
  }
}
test
for (us <- xml \\ "ul") {
  for (ul @ <ul>{ _* }</ul> <- us) {
    for (<li>{ li }</li> <- ul \ "li") {
      println(li)
    }
  }
}
hoge
fuge
<a href="url">hage</a>

Scala�ڎ��֖߂� / �Z�p�����֖߂�
���[���̑��M��F�Ђ�����

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@