1. 程式人生 > >快學scala第十六章習題——XML處理

快學scala第十六章習題——XML處理

本章主要講解對XML的處理,要處理xml需要引入scala-xml-x.x.x.x.jar包,建立普通scala 類不會自動新增此jar包,需要手動引入之後就可以使用了

1.(0)得到什麼,(0)(0)又得到什麼,為什麼?

仍然為<fred/>,<fred/>(0)代表節點本身,而且scala內部已實現了串接呼叫,所以<fred/>(0)(0)依然是節點本身

2.如下程式碼的值是什麼?

  • Opening bracket: [
  • Closing bracket: ]
  • Opening brace: {
  • Closing brace: }

你如何修復它?

xml報錯,將大括號改成兩個即可
  val a =
      <ul>
    <li>Opening bracket: [</li>
    <li>Closing bracket: ]</li>   
    <li>Opening brace: {{</li>   
    <li>Closing brace: }}</li>   
   </ul>;
    println(a(0));
    輸出
    <ul>
    <li
>
Opening bracket: [</li> <li>Closing bracket: ]</li> <li>Opening brace: {</li> <li>Closing brace: }</li> </ul>

3.比對

  • Fred
  • match { case
  • {Text(t)}
  • => t } 和
  • {“Fred”}
  • match { case
  • {Text(t)}
  • => t }
    為什麼它們的行為不同?
    第二種無法進行匹配,因為內嵌表示式中的字串並不會被轉成Text節點而是Atom[String]節點。這和普通的Text節點還是有區別的——Text是Atom[String]的子類。

    4.讀取一個XHTML檔案並列印所有不帶alt屬性的img元素。

    test.xhtml
    <html>
    <head>
    <title>My Scala</title>
    </head>
    <body>
    <p>Hello Scala</p>
    <p><img src="hamster.jpg" alt="TODO"/></p>
    <p><img src="frog.jpg" alt="TODO"/></p>
    <p><img src="dog.jpg" alt="inu"/></p>
    </body>
    </html>
    
    scala 程式碼:
    /*****第四題*******/
      def readfromXmL(path : String)={
         val root=XML.loadFile(path);
         val imgs=root \\ "img";獲取root下所有img檔案
         for(img<- imgs){
           if(img.attributes("alt")!=null){
             println(img);
           }
         }
      }

    5.列印XHTML檔案中所有影象的名稱。即,列印所有位於img元素內的src屬性值。
    xhtml檔案同上

      def PrintAllSrc(path : String)={
         val root=XML.loadFile(path);
         val imgs=root \\ "img";
         for(img<- imgs){
           if(img.attributes("src")!=null){
             println(img.attributes("src").text);
           }
         }
      }

    6.讀取XHTML檔案並列印一個包含了檔案中給出的所有超連結及其URL的表格。
    即,列印所有a元素的child文字和href屬性。

    xhtml檔案
    <html>
    <head>
    <title>My Scala</title>
    </head>
    <body>
    <p>Hello Scala</p>
    <p><img src="hamster.jpg"/></p>
    <p><img src="frog.jpg"/></p>
    <p><img src="dog.jpg" alt="inu"/></p>
    <ul>
    <li><a href="http://www.oschina.net/app" class='android' title='Android客戶端'>Android</a></li>
    <li><a href="http://www.oschina.net/app" class='iphone' title='iPhone 客戶端'>iPhone</a></li>
    <li><a href="http://www.oschina.net/app" class='wp7' title='Windows Phone 客戶端'>WP7</a></li>
    </ul>
    </body>
    </html>
    scala程式碼:
      def readfromA(path : String)={
        import java.io.InputStreamReader;
        import java.io.FileInputStream;
         val root=XML.load(new InputStreamReader(new FileInputStream(path),"UTF-8"));
         val as=root \\ "a";
         for(a<- as){
           if(a.attributes("href")!=null){
             println(a.attributes("href")+":"+a.text);
           }
         }
      }
    

    7.編寫一個函式,帶一個型別為Map[String, String]的引數,返回一個dl元素,其中針對對映中每個鍵對應有一個dt,每個值對應有一個dd。例如:
    Map(“A” -> “1”, “B” -> “2”)
    應產出

    A
    1
    B
    2
      def ChangeXml(ii:Map[String,String]):Elem={
        var a:Elem = <dl></dl>;
    
        <dl> {for ((k,v) <- ii) yield {
         <dt> {k} </dt><dd> {v} </dd>  ;
        } }</dl>
    
      }

    8.寫一個函式,接受dl元素,將它轉成Map[String,String]。該函式應該是前一個練習中的反向處理,前提是所有dt後代都是唯一(各不相同)的。

    def XmlChangeMap(elem:Elem):scala.collection.mutable.Map[String,String]={
    
        //var arr=new ArrayBuffer();
        var map:scala.collection.mutable.Map[String,String] = scala.collection.mutable.Map[String,String]();
        if(elem.label!="dl"){
          null;
        }else{
          val dt=elem \\ "dt";
          println(dt(1));
          val dd=elem \\ "dd";
          println(dd);
          println(0 until dt.size);
          for(i<- 0 until dt.size ){
            println(dt(i));
            if(!map.contains(dt(i).text)){
              map += (dt(i).text -> dd(i).text);
            }
          }
        }
        map;
      }
    1. 對一個XHTML文件進行變換,對所有不帶alt屬性的img元素新增一個alt=”TODO”屬性,其餘內容完全不變。
    def modifyxmlSaveDtD(path:String){
        import scala.xml.parsing.ConstructingParser;
        import java.io.File;
        val parser=ConstructingParser.fromFile(new File(path), preserveWS=true);
        val doc = parser.document();
        val root = doc.docElem;
        import scala.xml.transform._;
         val rule=new RewriteRule{
           override def transform(n:Node)= n match{
             case  [email protected] <img/>=> if(img.attributes("alt")==null) img.asInstanceOf[Elem] % Attribute(null, "alt", "TODO", scala.xml.Null) else img
             case _=>n;
           }
         }
         val trans=new RuleTransformer(rule).transform(root);
         XML.save(path,trans(0));
      }

    10.編寫一個函式,讀取XHTML文件,執行前一個練習中的變換,並儲存結果。確保儲存了DTD及所有CDATA內容。

    xhtml檔案
    <html>
    <head>
    <title>My Scala</title>
    <script>
    <![CDATA[
    function matchwo(a,b)
    {
    if (a < b && a < 0) then
      {
      return 1;
      }
    else
      {
      return 0;
      }
    }
    ]]>
    </script>
    </head>
    <body>
    <!-- This is a comment -->
    <p>Hello Scala</p>
    <p><img src="hamster.jpg" alt="TODO"/></p>
    <p><img src="frog.jpg" alt="TODO"/></p>
    <p><img src="dog.jpg" alt="inu"/></p>
    </body>
    </html>
    scala檔案:
     def modifyXml(path:String){
        import java.io.InputStreamReader;
        import java.io.FileInputStream;
         val root=XML.load(new InputStreamReader(new FileInputStream(path),"UTF-8"));
         val imgs=root \\ "img";
         import scala.xml.transform._;
         val rule=new RewriteRule{
           override def transform(n:Node)= n match{
             case  [email protected] <img/>=> if(img.attributes("alt")==null) img.asInstanceOf[Elem] % Attribute(null, "alt", "TODO", scala.xml.Null) else img
             case _=>n;
           }
         }
         val trans=new RuleTransformer(rule).transform(root);
         XML.save(path,trans(0));
    
    
      }