Có thể có một cách tốt hơn, nhưng một Bí quyết là để gọi invokeMethod
trực tiếp:
String buildCatalog(Catalog catalog) {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
delegate.invokeMethod('identity', [{
groupId(catalog.groupId)
artifactId(catalog.artifactId)
version(catalog.version)
}])
}
return writer.toString();
}
Đây là một cách hiệu quả những gì Groovy đang làm đằng sau hậu trường. Tôi không thể nhận được delegate.identity
hoặc owner.identity
để hoạt động, đó là các thủ thuật thông thường.
Chỉnh sửa: Tôi đã tìm hiểu điều gì đang xảy ra.
Groovy adds a method có chữ ký identity(Closure c)
cho mọi đối tượng.
Điều này có nghĩa là khi bạn cố gắng tự động gọi phần tử identity
trên trình tạo XML, trong khi truyền trong một đối số đóng, nó gọi phương thức identity()
, giống như gọi số delegate({...})
ở bên ngoài.
Sử dụng invokeMethod
các lực lừa để Groovy bỏ qua Giao thức đối tượng meta và coi phương thức là phương pháp động, mặc dù phương thức identity
đã tồn tại trên MetaObject.
Biết điều này, chúng tôi có thể tập hợp một giải pháp tốt hơn, dễ đọc hơn. Tất cả chúng ta phải làm là thay đổi chữ ký của phương pháp này, như vậy:
String buildCatalog(Catalog catalog) {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
// NOTE: LEAVE the empty map here to prevent calling the identity method!
identity([:]) {
groupId(catalog.groupId)
artifactId(catalog.artifactId)
version(catalog.version)
}
}
return writer.toString();
}
Đây là nhiều hơn nữa có thể đọc được, nó rõ ràng hơn mục đích, và những nhận xét nên (hy vọng) ngăn chặn bất cứ ai từ loại bỏ các "không cần thiết" trống rỗng bản đồ.
Điều đó có hiệu quả, nhưng bạn có thể giải thích điều này không? Đại biểu là gì và tại sao delegate.identity khác với delegate.invokeMethod ('Identity')? –
Tôi đã tìm ra, tôi sẽ cập nhật câu trả lời của mình. – OverZealous
FYI: Tôi đã theo dõi điều này bằng cách sử dụng GroovyConsole để kiểm tra đối tượng XML. Điều này cho tôi biết rằng phương thức 'identity' đã tồn tại với một' Closure' duy nhất làm đối số của nó. – OverZealous