2016年8月19日 星期五

使用Groovy在SAS中匯入JSON資料


描述
  JSON(Java Script Object Notation)是文字組成、被設計成我們可容易過目的一種開放標準資料格式,它奠基於JavaScript程序語言的一個子集和ECMA-262標準第三版(1999年12月)。在Base SAS 9.4中,有了PROC JSON可以產出JSON格式的資料,但仍舊沒有原生程序支援JSON的讀取。不過使用從SAS 9.3開放的PROC GROOVY,就能達到將JSON匯入SAS中的目的。
  Groovy是一種在JVM(Java Virtual Machine)上執行的動態語言,而PROC GROOVY能讓SAS程式碼在JVM上執行Groovy程式碼。此篇文章示範如何使用Groovy與XML Libname引擎(XML Libname Engine)將JSON轉成SAS資料集。

步驟
  1. 安裝Groovy語言
      這步是非必要的,但為了增加便利性,就是jar檔的取用,可以在這裡選擇你想安裝的方式。如果操作環境是在Windwos上,能考慮選用Windows Installer,因為安裝過程中,它能便捷地讓你設定環境變數與PATH的路徑,不像其它方式在安裝後,還需要特別到控制台或是透過命令列設定。
  2. 下載JAVA中的JSON套件
      到Sean Leary的GitHub相關頁面中下載所需的.java檔然後自己編譯成.jar檔或是直接到Maven Repository下載20140107版本、此套件的jar檔。
      個人建議可直接下載20140107版本的jar檔,因為在SAS中,有自己私有的JVM,我原先是使用Java 1.8去編譯此JSON套件成jar檔,但在PROC GROOVY中要使用到相關類別,都無法成功執行,log不是顯示無法解析我宣告的類別就是顯示版本不符合(我也不清楚為何錯誤訊息不會每次一樣)。
      可以確定的是,你要在SAS 9.4中成功使用這個套件,你可以選擇使用Java 1.7將這個套件編譯成jar檔或是直接從Maven Repository下載較舊日期的jar檔來使用。
  3. 將JSON轉成XML檔
      這是我們將要轉換的JSON檔:
    [
      {
        "LastName": "Orlando",
        "Age": 27,
        "PresentScore": 93,
        "TasteScore": 80,
        "Flavor": "Vanilla",
        "Layers": 1
      },
      {
        "LastName": "Ramey",
        "Age": 32,
        "PresentScore": 84,
        "TasteScore": 72,
        "Flavor": "Rum",
        "Layers": 2
      }
    ]
    可以從這個範例JSON檔發現它的結構是一個陣列,所以思維是在Groovy中用一個JSONArray來代表它,然後再轉成XML檔。程式碼如下:
    PROC GROOVY;
    ADD CLASSPATH="你Groovy底下embeddable目錄路徑\groovy-all-2.4.7.jar";
    ADD CLASSPATH="JSON套件jar檔放置的目錄路徑\json-20140107.jar";
    SUBMIT;
      import org.json.*;
      /* 從檔案中匯入json檔*/
      def json_string = new File("JSON檔放置的目錄路徑\\sample.json").text;
      JSONArray array = new JSONArray(json_string);
      String test="";
      /*將json檔轉成xml檔*/
      def out = new PrintWriter("要匯出的XML檔目錄路徑\\sample.xml");
      out.println("<xml>");
      for (int i = 0; i <array.length(); ++i) {
        test=XML.toString(array.getJSONObject(i), 'record');
        out.println(test);
      }
      out.println("</xml>");
      out.close();
    ENDSUBMIT;
    QUIT;
  4. 匯入XML檔成SAS資料集
    /*將XML檔轉成SAS資料集*/
    LIBNAME X XML "剛產出XML檔所放置的目錄路徑\sample.xml";
    LIBNAME S "你想存放的SAS資料集路徑";
    DATA S.sample;
    SET X.record;
    RUN;

後記
  如果你要處理的JSON檔有幾百MB或以上的等級,那麼在執行時有可能會遇到java.lang.OutOfMemoryError: Java heap space error的錯誤訊息,這時候你需要修改sasv9.cfg設定檔中,JREOPTIONS裏頭的-Xms-Xmx參數,譬如說原本是-Xms126m-Xmx126m,則依照自己安裝SAS的設備規格,去調整大小,像是-Xms1024m-Xmx1024m
  再來,你要處理的JSON檔結構很有可能會跟這個範例不一樣,像是你可能會遇到有許多根基JSON元素的文字檔,像是
{"PurchaseOrderID":1,"OrderQty":4,"UnitPrice":50.26,"LineTotal":201.04}
{"PurchaseOrderID":2,"OrderQty":3,"UnitPrice":45.12,"LineTotal":135.36}
{"PurchaseOrderID":2,"OrderQty":3,"UnitPrice":45.5805,"LineTotal":136.7415}
  那麼,你可以將文字檔讀入,將代表的字串物件以換行符號做分割轉成陣列物件,再將陣列物件轉成JSON陣列可以接受的參數,然後就可以按著上面的流程將JSON檔轉成SAS資料集了。
def json_string=new File("目錄路徑").text;
String[] items = json_string.split("\n");
String tmp = Arrays.toString(items);
JSONArray array = new JSONArray(tmp);
我要下載範例JSON檔練習。

參考
  1. Class Arrays. (n.d.). Retrieved from Java™ Platform, Standard Edition 7: https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html
  2. JSONArray. (n.d.). Retrieved from Android Developers: https://developer.android.com/reference/org/json/JSONArray.html
  3. Kennedy, J. (2016). Reading JSON in SAS® Using Groovy. 2016 Proceedings. Las Vegas, NV: SAS Global Forum.
  4. SAS Institute Inc. (2015). GROOVY Procedure. In Base SAS® 9.4 Procedures Guide, Fifth Edition. (pp. 975-984). Cary, NC: SAS Institute Inc.
  5. SAS® 9.4 Support for Java Runtime Environments. (n.d.). Retrieved from SAS: https://support.sas.com/resources/thirdpartysupport/v94/jres.html
  6. stleary. (2016, August 10). JSON-java. Retrieved from GitHub: https://github.com/stleary/JSON-java
  7. user1303007. (2012, March 30). How do I make a JAR from a .java. Retrieved from stackoverflow: http://stackoverflow.com/questions/9941296/how-do-i-make-a-jar-from-a-java
  8. vinod. (2013, November 14). Converting JSON to XML in Java. Retrieved from stackoverflow: http://stackoverflow.com/questions/19977979/converting-json-to-xml-in-java

分享:
Share to Facebook Share on Google Plus Share on Tumblr Share to Twitter Email This Pin This