4

我正在使用带有 XmlType 的 POJO 对象作为我为编组字符串映射而构建的自定义 XML 适配器。但是,我遇到了问题,让我可以正确使用空值。我能够让它工作,但我对它生成的 XML 不满意。

这是我目前正在使用的我想要工作的东西,但正如您在示例 XML 结果中看到的那样,它不包括正确的 xmlns:xsi="http://www.w3.org/2001/XMLSchema -instance" xsi:nil="true" 值

@XmlType(name="element")
public class RestMapElements {

  @XmlAttribute(name="name")
  public String key;
  @XmlValue
  public String value;

  public RestMapElements(String key, String value) {
    this.key = key;
    this.value = value;
  }
}

生成的 XML(精简为相关数据)。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
...
    <element-list>
        <item name="activated_date">2012-03-29 11:34:14.323</item>
        <item name="some_null_value"/>
    </element-list>
...

但是,我能够让它与它一起工作,我只是不满意 XML 必须在 item 标记内添加一个额外的“值”标记才能使其工作。(旁注,为什么将它命名为 item 而不是我试图在 XmlType 名称声明中指定的元素?)

@XmlType(name="element")
public class RestMapElements {

  @XmlAttribute(name="name")
  public String key;
  @XmlElement(nillable = true)
  public String value;

  public RestMapElements(String key, String value) {
    this.key = key;
    this.value = value;
  }
}

同样,生成的 XML(精简为相关数据)。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
...
<element-list>
    <item name="activated_date"><value>2012-03-29 11:34:14.323</value></item>
    <item name="some_null_value"><value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/></item>
</element-list>
...

真的,我可以使用第二个,因为它可以解决我的问题。我只是想将其用作学习经验,以查看使用注释的 JAXB 是否允许将其弯曲到我正在寻找的内容,而不必在项目标签下添加额外的值标签,这样我就可以支持空值. 现在,当它在第一个示例中解组时,我最终得到的是空字符串而不是 null。在第二个示例中,我得到了我期望的空值。

仅供参考:我目前正在使用 Jersey 1.11

4

2 回答 2

2

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB 2 (JSR-222)专家组的成员。

您可以使用 MOXy 的@XmlNullPolicy扩展来映射此用例:

休息地图元素

package forum10415075;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@XmlType(name="element")
public class RestMapElements {

  @XmlAttribute(name="name")
  public String key;

  @XmlValue
  @XmlNullPolicy(nullRepresentationForXml=XmlMarshalNullRepresentation.XSI_NIL)
  public String value;

}

package forum10415075;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Root {

    @XmlElementWrapper(name="element-list")
    @XmlElement(name="item")
    public List<RestMapElements> items = new ArrayList<RestMapElements>();

}

jaxb.properties

要将 MOXy 用作您的 JAXB (JSR-222) 提供程序,您需要添加一个jaxb.properties在与您的域模型相同的包中调用的文件,其内容如下:

javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory

演示

package forum10415075;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum10415075/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

输入.xml/输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <element-list>
      <item name="activated_date">2012-03-29 11:34:14.323</item>
      <item name="some_null_value" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
   </element-list>
</root>

笔记

如果您在 GlassFish 3.1.2 中使用 Jersey,则 MOXy 或 WebLogic 12.1.1 已包含:

于 2012-05-02T15:00:26.397 回答
0

我看到了你的问题。只有通过将您(或其他)中的相应条目设置为 ,才能生成带有的item元素,从而丢失属性。我认为没有太多的解决方案。xsi:nil="true"RestMapElementsArrayListnull

一种选择是从您的帖子开始使用您的编组,并使用以下内容解组:

如果你正在做这样的事情:

@XmlElementWrapper(name="element-list")
@XmlElement(name="item")
public ArrayList<RestMapElements> list;

您可以使用 aXmlAdapter检查是否value为空String并将其设置null为:

@XmlElementWrapper(name="element-list")
@XmlElement(name="item")
@XmlJavaTypeAdapter(ItemAdapter.class)
public ArrayList<RestMapElements> list;

并且ItemAdapter

public class ItemAdapter extends XmlAdapter<RestMapElements, RestMapElements> {

    @Override
    public RestMapElements unmarshal(RestMapElements v) throws Exception {
        if (v.value.equals("")) v.value = null;
        return v;
    }
}

虽然这仍然是不雅的恕我直言。如果你想生成正确的xsi:nil="true" item元素,这显然不是你想要的。

祝你好运。

于 2012-05-02T14:37:27.690 回答