Using Hashmap Syntax for Attributes
1: def p = """" ssn="555-11-2222">John Smith"""
2: def person = new XmlParser().parseText(p) // or XmlSlurper
@H_502_35@ 3: println person['@ID']
4: // ===> 99
5: ['ID','ssn'].each { att -> println person["@$att"] }
6: // ===>
7: // 99
8: // 555-11-2222
7.8 Navigating Deeply nested XML 1: def p = """"" 2: " >
@H_502_35@ 3: Jane
4: Doe
5: " >
6: 123 Main St
7: Denver
8: CO
9: 80020
10:
11: " >
12: 321 Tiam St
13: Denver
14: CO
15: 80020
16:
17: "
18:
19: def person = new XmlParser().parseText(p) //person = new XmlSlurper().parseText(p)
20: println person.address.street[1].text()
21: println person.address[1].street.text()
22: println person.address.street.text()
XmlParser sees the XML document as an ArrayList of nodes. This means
you have to use array notation all the way down the tree. XmlSlurper
sees the XML document as one big GPath query waiting to happen.
虽然有实现上的不同,但现在 XmlParser 和 XmlSlurper 已经越来越相像,基本上可以用前者的语法调用后者。
7.9 Parsing an XML document with namespaces在处理命名空间时,XmlParser 与 XmlSlurper 的区别比较明显:XmlParser 严格遵守命名空间;而 XmlSlurper 则默认忽略命名空间,除非你进行了声明:
1: def p_xml = """http://somewhere.org/person"2:8.4 Creating namespaced XML Using MarkupBuilder 1: def xml = new groovy.xml.MarkupBuilder()@H_502_35@ 3: xmlns:p="4: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"5: xsi:schemaLocation="http://somewhere.org/person6: http://somewhere.org/person.xsd"
7: ID="99" >8: John
9: Smith
10:
11: """http://somewhere.org/person" )12:
13: def person = new XmlParser().parseText(p_xml)
14: assert person.firstname == []
15:
16: def p = new groovy.xml.namespace("
17: //When dealing with namespaced elements,you can use only the HashMap notation18: println person[p.firstname].text()
19:
20: person = new XmlSlurper().parseText(p_xml)21: println person.firstname
22: assert person.'p:firstname' == ''23:
24: person.declarenamespace([p: 'http://somewhere.org/person'])25: println person.firstname
26: println person.'p:firstname'
2: def params = [:]
@H_502_35@ 3: params.'xmlns:product' = 'urn:somecompany:products'
4: params.'xmlns:vendor' = 'urn:somecompany:vendors'
5: params.ID = 99
6:
7: xml.person(params) {
8: 'product:name'('iPhone')
9: 'vendor:name'('Apple')
10: quantity(1)
11: }
8.5 Understanding the Difference Between MarkupBuilder and StreamingMarkupBuilder 前者为同步方法,会立即将结果输出到 stdout;后者为异步方法,在将 Builder 传递给 Writer 前,将不会产生文档,也不会有任何输出 前者的输出经过简单的格式化,是“给人读的”,后者则是未经格式化的字符串。 8.6 Creating Parts of the XML document Separately 1: def builder = new groovy.xml.StreamingMarkupBuilder() 2: def person1 = {
@H_502_35@ 3: person(ID:99){
4: firstname('John')
5: lastname('Smith')
6: }
7: }
8:
9: def comment = ' '
10: def cdata = " >< & Look 'at' me & >< "
11: def person2 = {
12: person(ID:100){
13: firstname('Jane')
14: lastname('Doe')
15: // Arbitrary Strings (Comments,cdaTA)
16: unescaped << comment
17: unescaped << "${cdata}"
18: out << comment
19: // Or
20: mkp.yIEldUnescaped(comment)
21: mkp.yIEld(comment)
22:
23: }
24: }
25: def personList = {
26: // XML Declaration
27: mkp.xmlDeclaration()
28: // Processing Instructions
29: mkp.pi('xml-stylesheet': "type='text/xsl' href='myfile.xslt'")
30: // namespace
31: mkp.declarenamespace('': 'http://myDefaultnamespace')
32: mkp.declarenamespace('location': 'http://someOthernamespace')
33: 'person-List' {
34: out << person1
35: out << person2
36: }
37: }
38:
39: builder.enCoding = 'UTF-8'
40: println builder.bind(personList)
41: // or new fileWriter('person.xml') << builder.bind(personList)
至此,简单的 XML 处理就都覆盖了。个人依然保持着对 XML 的无比厌恶……尤其是想到可以用 JsON 来代替网络数据交换这一点。到目前为止这本书没有对 XML (解析)性能浪费一点笔墨,如果你遇到一个两百兆的 XML 文件,是不是能用前述的方法解决就很难说了,但是——只要设计者脑子没有问题,我很难想出必须用巨大的 XML 文件的理由!而关于命名空间,我认为其纯属太空架构师试图赋予 XML 太多功能的结果。
8.13 Creating HTML on the Fly 1: new groovy.xml.MarkupBuilder().HTML { 2: head {
@H_502_35@ 3: Title('Search Results')
4: link(rel:'stylesheet',type:'text/CSS',href:'http://main.CSS')
5: script(type:'text/JavaScript',src:'http://main.Js')
7: body {
8: h1('Search Results')
9: div(ID:'results',class:'simple') {
10: table(border:1) {
11: tr {
12: th('name')
13: th('Address')
14: }
15: tr {
16: td {
17: a(href:'http://abc.org?ID=100','Jane Doe')
18: }
19: td('123 Main St')
20: }
21: }
22: }
24: }
9.3 Making an http GET Request 基本方式:
1: def page = new URL('http://www.aboutgroovy.com' ).text 2:
@H_502_35@ 3: new URL('http://www.aboutgroovy.com').eachline { line ->
4: println line
5: }
7: 'http://www.aboutgroovy.com'.toURL().text
Processing a Request Based on the http Response Code
1: def url = new URL('http://www.aboutgroovy.com') 2: def connection = url.openConnection()
@H_502_35@ 3: if(connection.responseCode == 200) {
4: println connection.content.text
5: } else {
6: println 'An error occurred:'
7: println connection.responseCode
8: println connection.responseMessage
9: }
9.5 Making an http POST Request 1: def url = new URL('http://search.yahoo.com/search') @H_502_35@ 3: //switch the method to POST (GET is the default)
4: connection.setRequestMethod('POST')
5: //write the data
6: def queryString = 'n=20&vf=pdf&p=groovy+grails'
7: connection.doOutput = true
8: Writer writer = new OutputStreamWriter(connection.outputStream)
9: writer.write(queryString)
10: writer.flush()
11: writer.close()
12: connection.connect()
13: //print the results
14: println connection.content.text
PUT 和 DELETE *** 作形式上同上。
RESTful POST Requests Using XML
1: def xml = """"" 2:
@H_502_35@ 3: Toyota
4: 2012
5: Prius
6: "
7: ...
8: connection.setRequestProperty('Content-Type','application/xml')
9: ...
10: writer.write(xml)
11: ...
10.1 discovering the Class 类的构造函数和实现的接口
1: println String.constructors 2: println String.interfaces
10.2 discovering the FIElds of a Class 1: def d = new Date() 2: // Calling getPropertIEs() on a class returns a java.util.HashMap of all the fIElds
@H_502_35@ 3: println d.propertIEs
4: // getDeclaredFIElds() method that returns an array of java.lang.reflect.FIEld objects
5: // reflecting all the fIElds declared by the class or interface represented by this
6: // Class object. This includes public,protected,default (package) access,and private
7: // fIElds,but excludes inherited fIElds.
8: println Date.declaredFIElds
9: // MetaClass
10: println Date.MetaClass
10.3 Checking for the Existence of a FIEld 1: class Person{ 2: String firstname,lastname
@H_502_35@ 3: }
4: def p = new Person()
5: // Will return the fIEld,not a boolean value!!
6: println Person.MetaClass.hasProperty(p,'firstname')
这个方法每次看到都想吐槽:典型的误导命名!
10.4 discovering the Methods of a Class 1: Date.class.methods 2: Date.methods
@H_502_35@ 3: Date.methods.name10.5 Checking for the Existence of a Method 1: p.MetaClass.respondsTo(p,'getFirstname') 10.7 Creating a Method Pointer 1: def List = []
2: def insert = List.&add
@H_502_35@ 3: insert 'Java'
10.8 Calling Methods That Don't Exist (invokeMethod) 2: String name @H_502_35@ 3: Map relationships = [:]
4: Object invokeMethod(String what,Object who) {
5: if(relationships.containsKey(what))
6: who.each { relationships.get(what) << it }
7: else
8: relationships.put(what,who as List)
9: }
10: }
11:
12: def scott = new Person(name: 'Scott')
13: scott.marrIEd 'Kim'
14: scott.kNows 'Ted','Ben'
15: scott.kNows 'Jared'
invokeMethod 可以说是 DSL 的基础,可以和 Scala 来比较下:形式上 Scala 的语法更自然(大多数时候没有 . 运算符),但论自由度 Groovy 则无疑胜出。
10.10 Adding Methods to a Class Dynamically (CategorIEs) 1: use(RandomHelper) { //use(RandomHelper,InternetUtils,SomeOthercategory) { ... } 2: 15.times{ println 10.rand() }
4:
5: class RandomHelper{
6: static r = new Random()
7: static int rand(Integer self){
8: r.nextInt(self.intValue())
10: }
10.11 Adding Methods to a Class Dynamically (ExpandoMetaClass) 1: Integer.MetaClass.rand = { new Random().nextInt(delegate.intValue()) } 2: 15.times { println 10.rand() }
动态语言的魔力啊。
总结以上是内存溢出为你收集整理的温故知新: Groovy Recipes (下)全部内容,希望文章能够帮你解决温故知新: Groovy Recipes (下)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)