要在Scala程序中加载已存在的XML文件,可以使用scala.xml.XML类中的load()方法。假设有如下XML文件,名为“books.xml”。
- <bookshelf>
- <book id="001">
- <name>Scala</name>
- <author>John</author>
- </book>
- <book id="002">
- <name>XML</name>
- <author>Tom</author>
- </book>
- </bookshelf>
加载XML文件的脚本如下:
- import scala.xml._ // 导入scala.xml包
- val xmlFile = XML.load("books.xml") // 加载XML文件
- println(xmlFile getClass)
- println(xmlFile)
- println("书的数目: " + (xmlFile \\ "book").size)
只是调用了XML类中的load方法而已,很简单,执行结果如下:
- class scala.xml.Elem
- <bookshelf>
- <book id="001">
- <name>Scala</name>
- <author>John</author>
- </book>
- <book id="002">
- <name>XML</name>
- <author>Tom</author>
- </book>
- </bookshelf>
- 书的数目: 2
接下来如果我们想要根据某本书的id来修改其书名,然后把修改之后的XML文件重新存储到硬盘当中,可以如下操作:
1、 先遍历整个<bookshelf>…</bookshelf>获得所有的<book>…</book>元素对;
2、 分别提取出上面获得的<book>…</book>中的每个id和name,并建立一个id到name之间的映射Map[String, String]对象;
3、 将获得的所有映射Map[String, String]对象保存到bookMap变量中;
4、 重新创建一个以<bookshelf>…</bookshelf>为根节点的XML文件(即scala.xml.Elem对象),将上面获得的bookMap变量中包含的Map[String, String]对象逐一地更新、修改;
5、 最后将更新后的XML保存起来,调用XML.save方法。
具体代码如下:
- // id与name的映射变量
- val bookMap =
- (Map[String, String]() /: (xmlFile \ "book")) {
- (map, bookNode) =>
- val id = (bookNode \ "@id").toString
- val name = (bookNode \ "name").text.toString
- map(id) = name
- }
上面的Map[String, String]() 是/: 方法的初始变量,也表明了该表达式返回的map(id) = name 将会是Map[String, String] 类型。另外bookNode \ "@id" 则是提取出book元素中的id属性值。
- // 新的Elem对象
- val newXmlFile =
- <bookshelf>
- { bookMap.map{updateXmlFile} }
- </bookshelf>
这只是定义一个以<bookshelf>…</bookshelf>为根节点的XML文件(即scala.xml.Elem对象),它对bookMap中的每一个Map[String, String] 对象执行updateXmlFile方法(即传名参数)。
- // 更新、修改原XML文件
- def updateXmlFile(elem: (String, String)) = {
- val (id, newName) = elem // 二元组
- <book id={id + "-01"}>
- <name>{newName + " Programming"}</name>
- </book>
- }
- XML.save("newXmlFile.xml", newXmlFile)
- println(XML.load("newXmlFile.xml"))
XML.save方法将会将newXmlFile 以名为“newXmlFile.xml”保存到当前目录下。执行后生成的的newXmlFile.xml 内容如下:
- <bookshelf>
- <book id="001-01">
- <name>Scala Programming</name>
- </book><book id="002-01">
- <name>XML Programming</name>
- </book>
- </bookshelf>
嗯,格式有点不美观,问题在于脚本代码中关于尖括号和花括号间的空格、换行等等有关,我调整了多次都达不到期望的效果...毕竟Scala的默认缩进是2个空格。
注:Scala中代码块的最后一个语句作为默认返回值(如果需要返回)在这里体现得比较明显,如果不知道这一点,则上面的代码可能有些难懂。
发现的问题如下:
1、如果原XML文件中的节点元素存在中文,则会修改出错,抛出以下异常:java.nio.charset.UnmappableCharacterException: Input length = 1;
2、同上面类似,如果脚本代码中包含中文字符,如书名号《》等,也会有上面的问题出现;尽管我在执行时使用了scala -encoding gb2312 编码;
本文转自 xxxx66yyyy 51CTO博客,原文链接:http://blog.51cto.com/haolloyin/395871,如需转载请自行联系原作者