如何使用Grails XML marshaller从编组中排除null属性

时间:2014-02-14 20:13:41

标签: grails

在Grails 2.3.5中编组为XML时,我希望从XML中排除null属性。

目前这样的代码

if ( myObj.someProp == null ) log.info("yeap, it's null")
render myObj as XML

将向日志输出“yeap,它为null”,然后呈现看起来像

的XML
<myObj>
    <someProp />
</myObj>

但我想要的是

<myObj>
</myObj>

或者简单地说(如果没有其他属性)

<myObj />

是否可以将Grails配置为从编组中排除空属性?

另外,使用

def xml = myObj as XML
if ( myObj.someProp == null ) {
    xml.excludes = ["someProp"]
}
render xml

不会在所有情况下都有效,因为有时它是results的列表,其中列表中的项可能具有空属性。

更新

我通过将以下代码添加到BootStrap.groovy来尝试@ dmahapatro的建议

    XML.registerObjectMarshaller(MyObj) {
        it.properties.findAll { it.value != null }
    }

使用适当的import语句。

结果是不正确的XML:

<myObj>
    <entry key="someProp">non-null value</entry>
</myObj>

现在属性不再是标签的名称。相反,使用通用的“entry”标记,因为Grails看到的是Map而不是域对象。

2 个答案:

答案 0 :(得分:1)

您可以使用registerObjectMarshaller修改该行为。

//Bootstrap.groovy
import grails.converters.XML
import my.package.MyObj

XML.registerObjectMarshaller(MyObj) {
    it.properties.findAll { it.value != null }
}

<强>更新
为了避免由于域类的映射表示而导致的入口标记,可以很容易地转换对象编组器以获得预期结果,如下所示:

XML.registerObjectMarshaller(Author) {obj, xml ->
    xml.attribute 'id', "$obj.id"
    xml.build {
        obj.properties.each {
            if(it.value != null) {
                "$it.key" it.value
            }
        }
    }
}

答案 1 :(得分:1)

使用内置转换器和marshallers无法从输出中排除空值的标签。阅读了Grails源代码后,有两个相关的类可以控制这种行为,这两个类都不能配置为表现不同。

第一个是DomainClassMarshaller中的编组类grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/web/converters/marshaller/xml/,相关的行是

xml.startNode(propertyName);
if (!property.isAssociation()) {
    // Write non-relation property
    Object val = beanWrapper.getPropertyValue(propertyName);
    xml.convertAnother(val);
}

这将启动属性的节点(无论其值如何),然后对值调用xml.convertAnother

第二个相关的代码行是convertAnother XML.java中的grails-plugin-converters/src/main/groovy/grails方法

if (o == null) {
    // noop
}

如果值为null(保留标记为空)并且不引用任何配置选项以使其行为不同,则不执行任何操作。

因此,获得所需行为的唯一方法是从头开始实现它,并将自定义编组器/转换器注册为@dmahapatro建议。

由于OP询问如何使用Grails XML Marshaller执行此操作,因此正确的答案很简单:无法完成。