最小故障、无故障和限制的目的是什么?

2022-09-03 01:29:31

所需文件说:

如果是 ,则 Javabean 属性映射到 XML 模式元素声明,并带有 。 表示单值属性和多值属性。required()trueminOccurs="1"maxOccurs"1""unbounded"

如果是 ,则 Javabean 属性映射到 XML Schema 元素声明,并带有 。 表示单值属性和多值属性。required()falseminOccurs="0"maxOccurs"1""unbounded"

nillable的文档说:

如果是 ,则 JavaBean 属性映射到 XML Schema 元素声明。nillable()truenillable


代码 :xs:complexType
public class WSData {
    //...

    @XmlElement(required = true, nillable = false)
    public void setMonth(XmlMonthType month) {
        this.month = month;
    }

    public void setUserLogin(String userLogin) {
        this.userLogin = userLogin;
    }
}

代码 :xs:simpleType

@XmlType
@XmlEnum(Integer.class)
public enum XmlMonthType {
    @XmlEnumValue("1")
    JANUARY,
    @XmlEnumValue("2")
    FEBRUARY,
    @XmlEnumValue("3")
    MARCH,
    /* ... months 4 ~9 ... */
    @XmlEnumValue("10")
    OCTOBER,
    @XmlEnumValue("11")
    NOVEMBER,
    @XmlEnumValue("12")
    DECEMBER;
}

生成的 XML 架构:

<xs:complexType name="wsData">
  <xs:sequence>
    <xs:element name="month" type="xs:string"/>
    <xs:element minOccurs="0" name="userLogin" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

<xs:simpleType name="xmlMonthType">
  <xs:restriction base="xs:int">
    <xs:enumeration value="1"/>
    <xs:enumeration value="2"/>
    <xs:enumeration value="3"/>
    <!-- ... months 4 ~9 ... -->
    <xs:enumeration value="10"/>
    <xs:enumeration value="11"/>
    <xs:enumeration value="12"/>
  </xs:restriction>
</xs:simpleType>


事实:
  1. 最小故障的默认值为 1。因此,月份是必需的(必须存在);
  2. 月份有限制。因此,month 只能有一个由 12 个定义的枚举之一定义的值;
  3. nillable 的默认值为 false。因此,月份不能有空值;
  4. 正确生成 XML 架构。

问题:

  1. 它正在接受月份的abcense(一定不存在);
  2. 它接受月份的任何值,例如13(除非无法解析为整数);
  3. 它接受空值;

我没想到会有这些问题,我错过了什么吗?
如果该行为是正确的,那么必需的,可否定的和xs:限制的目的是什么?


答案 1

Nillable 允许空值。例如,如果您有一个整数或一个日期,如果它是 nillable,则 XML 标记可以为空。如果它不是不可或不需要的,则XML元素必须与有效内容一起存在,或者根本不存在;空标记无效。


答案 2

使最小次数为1,使月份成为必需的;

的默认值为 1,因此该元素是必需的。请注意如何必须添加以使其成为可选的。minOccursmonthminOccurs="0"userLogin

<xs:complexType name="wsData">
  <xs:sequence>
    <xs:element name="month" type="xs:string"/>
    <xs:element minOccurs="0" name="userLogin" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

使用生成的限制验证月份(不使用 XmlAdapter)。

您可以在 Unmarshaller 上设置一个实例以验证输入:Schema

演示

下面的代码可用于生成 XML 架构:

package forum9111936;

import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;

public class Demo {

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

            @Override
            public Result createOutput(String namespaceUri,
                    String suggestedFileName) throws IOException {
                StreamResult result = new StreamResult(System.out);
                result.setSystemId(suggestedFileName);
                return result;
            }

        };
        jc.generateSchema(sor);
        System.out.println();
    }

}

更新

JAXB RI 通常会针对转换问题引发严重性为 1 的重试。默认值忽略严重性小于 2 的所有问题。这通常会导致该值设置为 null。您可以按如下方式覆盖:ValidationEventValidationEventHandlerValidationEventHandler

    unmarshaller.setEventHandler(new ValidationEventHandler() {
        @Override
        public boolean handleEvent(ValidationEvent event) {
            System.out.println(event);
            return event.getSeverity() < ValidationEvent.ERROR;
        }
    });

但是,JAXB RI 似乎不会引发与转换枚举值相关的事件(可能的错误)。如果您碰巧使用EclipseLink JAXB(MOXy)作为您的JAXB提供程序,那么您将收到如下异常:

Exception in thread "main" Local Exception Stack: 
Exception [EclipseLink-116] (Eclipse Persistence Services - 2.4.0.qualifier): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: No conversion value provided for the value [13] in field [month/text()].
Mapping: org.eclipse.persistence.oxm.mappings.XMLDirectMapping[month-->month/text()]
Descriptor: XMLDescriptor(forum9111936.WSData --> [])
    at org.eclipse.persistence.exceptions.DescriptorException.noFieldValueConversionToAttributeValueProvided(DescriptorException.java:1052)
    at org.eclipse.persistence.mappings.converters.ObjectTypeConverter.convertDataValueToObjectValue(ObjectTypeConverter.java:140)
    at org.eclipse.persistence.oxm.mappings.XMLDirectMapping.getAttributeValue(XMLDirectMapping.java:287)
    at org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue.endElement(XMLDirectMappingNodeValue.java:190)
    at org.eclipse.persistence.oxm.record.UnmarshalRecord.endElement(UnmarshalRecord.java:910)
    at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parseEvent(XMLStreamReaderReader.java:133)
    at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:83)
    at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:72)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:838)
    at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:626)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:472)
    at forum9111936.Demo2.main(Demo2.java:30)

详细信息


推荐