我正在尝试让MOXy或JAXB RI将空集合封送到xsi:nil元素,如下所示:
<element xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
用例是:
我知道从2.2.6开始的JAXB RI可能无法做到这一点,但也许我错过了一些东西。我检查了源代码,它基本上说是非参数化的:“如果它是一个List,如果它是null,只有在字段上存在@XmlElementWrapper时才输出任何内容”。但不幸的是,这不是这种情况的解决方案。
我尝试了MOXy并使用了@XmlNullPolicy注释,但它似乎对集合属性没有影响。还有另一种方法可以为emtpty集合制作MOXy输出xsi:nil元素吗?
我创建了一个测试用例来举例说明会发生什么。第一个和第二个是实际结果和我需要的结果。第三个是为第四个代码块中的实际用例启用MOXy所需的jaxb.properties文件。
这是我在底部执行测试用例时得到的结果:
<?xml version="1.0" encoding="UTF-8"?>
<model>
<nonCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<nonCollectionEmptyNode/>
<wrappedNullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</model>
这就是我需要的:
<?xml version="1.0" encoding="UTF-8"?>
<model>
<nonCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<nonCollectionEmptyNode/>
<nullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<wrappedNullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</model>
jaxb.properties 此文件需要与下面的测试用例位于同一个包中,否则将不使用MOXy。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
测试案例
package test;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlMarshalNullRepresentation;
import org.eclipse.persistence.oxm.annotations.XmlNullPolicy;
/**
* jaxb.properties containing string:
* "javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory"
* needs to be in the same package as this class to enable MOXy.
*/
public class XmlNullPolicyTest
{
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
private static class Model
{
/**
* Outputs xsi:nil elements when using JAXB RI or MOXy.
*/
@XmlElement(required = true, nillable = true)
protected String nonCollection;
/**
* This is here to test if the EclipseLink implementation is actually used.
* To enable MOXy JAXB impl put jaxb.properties containing text
* "javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory"
* in the same package as this class.
*
* Using the RI it outputs:
* <nonCollectionEmptyNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
*
* And with MOXy, because it processes @XmlNullPolicy:
* <nonCollectionEmptyNode/>
*/
@XmlElement(required = true, nillable = true)
@XmlNullPolicy(
nullRepresentationForXml = XmlMarshalNullRepresentation.EMPTY_NODE
)
protected String nonCollectionEmptyNode;
/**
* Need this one to work. Should marshal to:
* <nullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
* ...if possible.
*/
@XmlElement(required = true, nillable = true)
@XmlNullPolicy(
nullRepresentationForXml = XmlMarshalNullRepresentation.XSI_NIL,
xsiNilRepresentsNull = true
)
private List<String> nullCollection = null;
/**
* Cannot use this one, since it the service expects elements unwrapped.
* Works though as long as the list is actually null.
*/
@XmlElement(required = true, nillable = true)
@XmlElementWrapper(nillable = true)
private List<String> wrappedNullCollection = null;
}
public static void main(String[] args)
throws JAXBException
{
final JAXBContext jaxbContext =
JAXBContext.newInstance(Model.class);
final Marshaller marshaller =
jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(new Model(), System.out);
}
}
我感谢任何帮助。
感谢您的关注!
祝你好运, 基督教
答案 0 :(得分:0)
具有以下内容表示集合属性为null。
<fieldName xsi:nil=“true”…/>
当以下内容代表填充的集合时:
<fieldName>foo</fieldName>
<fieldName>bar</fieldName>
有点奇怪,因为<fieldName xsi:nil=“true”…/>
将被解释为包含一个空条目的集合。
正如您通常使用JAXB提到的那样,您将使用@XmlElementWrapper
并使包装元素指示该集合为空。
我会调整您的数据以获得您想要的XML表示。您可以通过在编组事件之前和之后利用来实现此目的。如果before事件将任何null
值转换为包含List
值的大小为1的null
。然后在after unmarshal事件中将包含List
值的null
大小设置回null
。
可以使用Marshal.Listener
:
或者在类的回调方法中: