Исключение Groovy MarkupBuilder при создании тега "id"
Я пытаюсь создать XML-фид, а MarkupBuilder в Groovy доставляет мне головную боль:
def newsstandFeed(def id) {
def publication = Publication.get(id)
def issues = issueService.getActiveIssuesForPublication(publication)
def updateDate = DateUtil.getRFC3339DateString(publication.lastIssueUpdate)
def writer = new StringWriter()
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
def xml = new MarkupBuilder(writer)
xml.feed('xmlns':"http://www.w3.org/2005/Atom", 'xmlns:news':"http://itunes.apple.com/2011/Newsstand") {
updated("${updateDate}")
issues.each { issue ->
entry {
id (issue.id)
updated("${DateUtil.getRFC3339DateString(issue.lastUpdated)}")
published("${DateUtil.getRFC3339DateString(issue.releaseDate)}")
summary(issue.summary)
"news:cover_art_icons" {
"news:cover_art_icon" (size:"SOURCE", src:"${issue.cover.remotePath}")
}
}
}
}
return writer.toString()
}
Я получаю это исключение:
Class groovy.lang.MissingMethodException
No signature of method: java.lang.String.call() is applicable for argument types: (org.codehaus.groovy.runtime.GStringImpl) values: [CYB_001] Possible solutions: wait(), any(), wait(long), any(groovy.lang.Closure), take(int), each(groovy.lang.Closure)
"CYB_001" является первым атрибутом "id".
Если я переименую "id" в "id" или во что-то еще, это сработает и вернет правильный XML-документ:
....
issues.each { issue ->
entry {
ids ("${issue.id}")
...
Любые идеи, почему это происходит, и как я могу обойти проблему?
Окружение - Grails 2.1.1 (поэтому Groovy 1.8, я полагаю)
2 ответа
Мне кажется, что ваш XML-компоновщик пытается сослаться на некоторую строковую переменную в среде. Поскольку Groovy Builder перехватывает пропущенные вызовы методов, если они найдут ссылку, они попытаются применить к ней. Следующий код может воспроизвести вашу ошибку:
def id = ""
new groovy.xml.MarkupBuilder().xml {
id "90"
}
И следующее хорошо:
def ids = ""
new groovy.xml.MarkupBuilder().xml {
id "90"
}
Переименование вашего id
переменная должна сделать свое дело
Обновить:
Альтернативный способ использовать тег с тем же именем, что и переменная в области видимости, - использовать (некрасивую) строку GString:
def id = ""
new groovy.xml.MarkupBuilder().xml {
"${'id'}" "90"
}
столкнуться с той же ситуацией и квалифицировать ее с помощью застройщика, решившего проблему для меня.
def writer = new StringWriter()
def builder = new MarkupBuilder(writer)
builder.executions() {
project.scalaVersions.each { scalaVersion ->
def scalaMajorVer = '_' + scalaVersion.split('\\.')[0..1].join('.')
def artifactIdStr = publication.artifactId.replaceAll(/_[0-9.]+$/, '') + scalaMajorVer
execution() {
builder.id(artifactIdStr) // qualify with builder to avoid collision
phase('deploy')
goals() { goal('deploy-file') }
configuration() {
groupId(publication.groupId)
artifactId(artifactIdStr)
builder.version(project.version) // ditto.
}
}
}
}