Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调用JAXB getter会导致输出xs:list类型的空属性值_Java_Xml_Xsd_Jaxb_Xjc - Fatal编程技术网

Java 调用JAXB getter会导致输出xs:list类型的空属性值

Java 调用JAXB getter会导致输出xs:list类型的空属性值,java,xml,xsd,jaxb,xjc,Java,Xml,Xsd,Jaxb,Xjc,我试图处理这样一种场景:调用jaxb生成的getter(对于类型为xs:list的属性值)会导致创建一个空的ArrayList,然后在输出XML时将其编组为空字符串。空字符串属性值输出破坏了其他生产代码,因此我不希望输出这些代码(如果它们不在输入XML中) 我尝试过使用定制的XmlAdapter marshall方法,但是当我配置它时,jaxb 生成的getter实现已更改,它不再创建空的ArrayList,该ArrayList会使用NullPointerException中断现有代码 以下是更

我试图处理这样一种场景:调用jaxb生成的getter(对于类型为xs:list的属性值)会导致创建一个空的ArrayList,然后在输出XML时将其编组为空字符串。空字符串属性值输出破坏了其他生产代码,因此我不希望输出这些代码(如果它们不在输入XML中)

我尝试过使用定制的XmlAdapter marshall方法,但是当我配置它时,jaxb 生成的getter实现已更改,它不再创建空的ArrayList,该ArrayList会使用NullPointerException中断现有代码

以下是更详细的背景信息。 我正在使用jaxb从XML模式生成Java类。 这是通过ANT目标完成的:

<java classname="com.sun.tools.internal.xjc.XJCFacade" failonerror="true">
    <arg value="-d"/>
    <arg value="${generated.dir}"/>
    <arg value="-p" />
    <arg value="com.myorg.model"/>
    <arg value="-b" />
    <arg value="${basedir}/bindings.xjb"/>
    <arg value="${schema.dir}/Test.xsd" />
</java>
如果我将其解组到RootElement对象并调用getter:

List<String> myRefs = rootElement.getChildElement().get(0).getMyRefs();
我的AttributeListConverter类:

package com.myorg.model.utils;

import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;

public class AttributeListConverter {
    private static final Splitter SPACE_SPLITTER = Splitter.on(' ').trimResults().omitEmptyStrings();

    public static List<String> unmarshal(String spaceSeparatedList) {
        return StringUtils.isEmpty(spaceSeparatedList) ? new ArrayList<String>() : SPACE_SPLITTER.splitToList(spaceSeparatedList);
    }
    
    public static String marshal(List<String> attributeList) {
        return (attributeList == null || attributeList.isEmpty()) ? null : Joiner.on(" ").join(attributeList);
    }
}
package com.myorg.model.utils;
导入java.util.ArrayList;
导入java.util.List;
导入org.apache.commons.lang.StringUtils;
导入com.google.common.base.Joiner;
导入com.google.common.base.Splitter;
公共类AttributeListConverter{
私有静态最终拆分器空间_Splitter=Splitter.on(“”).trimResults().omitEmptyStrings();
公共静态列表解组(字符串空格分隔列表){
返回StringUtils.isEmpty(spaceSeparatedList)?new ArrayList():SPACE\u SPLITTER.splitToList(spaceSeparatedList);
}
公共静态字符串封送处理(列表属性列表){
return(attributeList==null | | attributeList.isEmpty())?null:Joiner.on(“”).join(attributeList);
}
}
marshal()方法中,当列表为null或空时,通过返回null,不会输出MyRefs属性

但是,自动生成的RootElement.java类现在已更改:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
public static class ChildElement {

    @XmlAttribute(name = "MyRefs")
    @XmlJavaTypeAdapter(Adapter28 .class)
    protected List<String> myRefs;

    /**
     * Gets the value of the myRefs property.
     * 
     * @return
     *     possible object is
     *     {@link java.lang.String }
     *     
     */
    public List<String> getMyRefs() {
        return myRefs;
    }

    /**
     * Sets the value of the myRefs property.
     * 
     * @param value
     *     allowed object is
     *     {@link java.lang.String }
     *     
     */
    public void setMyRefs(List<String> value) {
        this.myRefs = value;
    }

}
@xmlacessortype(xmlacesstype.FIELD)
@XmlType(name=”“)
公共静态类子元素{
@XmlAttribute(name=“MyRefs”)
@XmlJavaTypeAdapter(Adapter28.class)
受保护列表myRefs;
/**
*获取myRefs属性的值。
* 
*@返回
*可能的对象是
*{@link java.lang.String}
*     
*/
公共列表getMyRefs(){
返回myRefs;
}
/**
*设置myRefs属性的值。
* 
*@param值
*允许的对象是
*{@link java.lang.String}
*     
*/
公共void setMyRefs(列表值){
this.myRefs=值;
}
}
getMyRefs()方法不再检查null,而是返回一个空的ArrayList,它只是直接返回myRefs值

这样做的副作用是破坏其他始终假定getMyRefs()永远不会为null的代码(它们现在抛出NullPointerException)

使用自定义marsall()方法确实解决了输出空MyRefs属性的问题,但是它破坏了依赖于getMyRefs()而不返回null的其他功能

我有没有办法达到我要求的行为

List<String> myRefs = rootElement.getChildElement().get(0).getMyRefs();
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RootElement xmlns="http://www.opentravel.org/OTA/2003/05">
    <ChildElement MyRefs=""/>
    <ChildElement MyRefs="1 2 3 4"/>
    <ChildElement/>
</RootElement>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
          xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          xmlns:ota="http://www.opentravel.org/OTA/2003/05"
          version="2.1">
          
    <!-- This file handles exceptions in the JAXB source code generation-->
          
    <!-- Global type bindings -->
    <globalBindings typesafeEnumMaxMembers="380">
        <javaType name="java.util.List&lt;String&gt;" xmlType="ota:ListOfRefs" parseMethod="com.myorg.model.utils.AttributeListConverter.unmarshal" printMethod="com.myorg.model.utils.AttributeListConverter.marshal"/>
    </globalBindings>
</bindings>
package com.myorg.model.utils;

import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;

public class AttributeListConverter {
    private static final Splitter SPACE_SPLITTER = Splitter.on(' ').trimResults().omitEmptyStrings();

    public static List<String> unmarshal(String spaceSeparatedList) {
        return StringUtils.isEmpty(spaceSeparatedList) ? new ArrayList<String>() : SPACE_SPLITTER.splitToList(spaceSeparatedList);
    }
    
    public static String marshal(List<String> attributeList) {
        return (attributeList == null || attributeList.isEmpty()) ? null : Joiner.on(" ").join(attributeList);
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
public static class ChildElement {

    @XmlAttribute(name = "MyRefs")
    @XmlJavaTypeAdapter(Adapter28 .class)
    protected List<String> myRefs;

    /**
     * Gets the value of the myRefs property.
     * 
     * @return
     *     possible object is
     *     {@link java.lang.String }
     *     
     */
    public List<String> getMyRefs() {
        return myRefs;
    }

    /**
     * Sets the value of the myRefs property.
     * 
     * @param value
     *     allowed object is
     *     {@link java.lang.String }
     *     
     */
    public void setMyRefs(List<String> value) {
        this.myRefs = value;
    }

}