iT邦幫忙

DAY 16
2

邊看邊學Groovy/Grails/Gradle系列 第 13

Groovy基本語法(6)-Parseing XML(2)-using XmlParser/XmlSlurper

  • 分享至 

  • xImage
  •  

昨天分享的是用java API以及DOM builder來解析XML,今天要跟大家分享的是於groovy.util裡的兩個處理XML的方法(XmlParser/XmlSlurper),個人覺得非常直觀,兩者用法在存取node的時,語法大同小異皆透過GPath的調調來取得node資訊,GPath的調調(這樣的講法有點不專業)就是root.children.grandchild.xxx()取得資訊,而變數名稱即為xml裡的tag名稱,故較為直觀,XmlParser和XmlSlurper最大的差異在於XmlSlurper較為適合走訪整個xml結構,從最外層到最內層,而XmlParser因其API建立於groovy.util.Node上,走訪的方法回傳的是list而非iterator,故需再自行撰寫iterator語法,而XmlSlurper則建立在GPathResult上,相同方法回傳即為iterator,不須額外撰寫程式碼,但對於存取node的資訊來說兩者皆可以達到,更深入的方法需參考官方API,
先把昨天的XML檔再放上來

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane prefHeight="387.0" prefWidth="451.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.RoutineCopyController">
  <!-- TODO Add Nodes -->
  <bottom>
    <Label alignment="CENTER" contentDisplay="CENTER" text="Copy Right By DNE I&C" BorderPane.alignment="CENTER" />
  </bottom>
  <center>
    <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" spacing="20.0">
      <children>
        <ProgressIndicator fx:id="progressIndicator" focusTraversable="false" prefHeight="132.0" prefWidth="475.0" progress="0.0" />
        <Label fx:id="copyMessage" prefHeight="34.0" prefWidth="4750" text="" />
        <Button fx:id="copyButton" mnemonicParsing="false" onAction="#beginCopy" text="Copy" />
      </children>
    </VBox>
  </center>
  <top>
    <Label alignment="CENTER" contentDisplay="CENTER" text="Daily Copy Program" textAlignment="CENTER" BorderPane.alignment="CENTER" />
  </top>
</BorderPane>

首先看XmlParser範例,因該API屬groovy.util底下,故不需要import

//import groovy.util.XmlParser 預設有import,本行可不寫

def root = new XmlParser().parse((new File('D:\\groovy\\mygroovy\\src\\layout.xml')))
//parse()方法支援很多種input,詳官方API
//XmlParser對於取得xml node資訊很方便,使用GPath語法很快就可以存取node/tag的屬性或名稱
println "The main container is ${root.name()}"//text()回傳的是字串
println "The major UIs are located in ${root.center[0].name()}"
//與DOMBuilder相同可以以xml檔裡面的tag作為存取名稱
println "The UIs are organized by ${root.center.VBox[0].name()}"+
			 "with spacing ${root.center.VBox.@spacing}"
			 //使用.@attributeName可取得tag裡attribute的值
println "The program has a"+
			" ${root.center.VBox.children.ProgressIndicator[0].name()}"+
			"to indicate the progress" //value()回傳的是list

執行結果:

The main container is BorderPane
The major UIs are located in center
The UIs are organized by VBoxwith spacing [20.0]
The program has a ProgressIndicatorto indicate the progress

再來簡單分享XmlSlurper走訪範例

def fxroot= new XmlSlurper().parse((new File('D:\\groovy\\mygroovy\\src\\layout.xml')))

println "${fxroot.name()}'s pre-defined height is ${fxroot.@prefHeight}" 
//使用.@attributeName可取得tag裡attribute的值
/*XmlSlurper中的方法支援GPathResult,意思是在於可以使用operator(*.)往下一層走訪
 * 而XmlParser方法則是參考groovy.util.Node,對於以下的breadthFirst語法預設回傳是List
 * 對於走訪整個xml的文件結構相對於比較麻煩,因為還要多一道Iterator步驟,
 * XmlParser及XmlSlurper各有各的優點,視情況而定吧!
 */
print fxroot.center.breadthFirst()*.name().join('->')
//從center這個node/tag往下走訪 
// Operator(*.)白話一點就是對一每個tag呼叫Join方法,相當於Iterator
print '\n'
print fxroot.center.depthFirst()*.name().join('<-')

執行結果:

BorderPane's pre-defined height is 387.0
center->VBox->children->ProgressIndicator->Label->Button
center<-VBox<-children<-ProgressIndicator<-Label<-Button

1.主要差異
XmlParser XmlSlurper
List depthFirst() Iterator depthFirst()
List breadthFirst() Iterator breadthFirst()

2.因時間的關係,我沒有仔細去看breadthFirst()跟depthFirst的差異,兩者的輸出結果在這個例子是一樣的,但我相信兩個方法還是有本質上的差異,有興趣麻煩大家看一下官方API


上一篇
Groovy基本語法(6)-Parseing XML(1)-DOM
下一篇
建立Grails安裝開發環境
系列文
邊看邊學Groovy/Grails/Gradle27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言