Исключение 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.
                }
            }
        }
    }
Другие вопросы по тегам