是否可以有XML,适当的XSD,可以选择maxOccurs =" 1"和minOccurs =" 1"?

时间:2015-02-10 17:34:36

标签: xml xsd jaxb

我有有效的XSD,但我不能制作xml,适合它。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns="urn:hl7-org:v3" xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="urn:hl7-org:v3"
           elementFormDefault="qualified">

    <xs:element name="Main" type="Main"/>
    <xs:complexType name="Child1">
        <xs:sequence>
            <xs:element name="f1" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Child2">
        <xs:sequence>
            <xs:element name="f1" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Main">
        <xs:sequence>
            <xs:choice>
                <xs:element name="child1" type="Child1"
                            nillable="true"
                            minOccurs="1"
                            maxOccurs="1"/>
                <xs:element name="child2" type="Child2"
                            nillable="true"
                            minOccurs="1"
                            maxOccurs="1"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

如果这是不可能的,为什么架构有效? 使用JAXB为此模式生成源,创建对象,但验证不通过 - [找到无效的内容,以元素&#39; child1&#39;开头。此时不会有子元素。]

import cz.atria.common.datagenerator.ValueProvider;
import cz.atria.common.datagenerator.ValueProviderRandom;
import org.hl7.v3.Child1;
import org.hl7.v3.Main;
import org.hl7.v3.ObjectFactory;
import org.junit.Test;

import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.File;

public void test1() throws Exception {
    JAXBContext jaxbContext = JAXBContext.newInstance(Main.class.getPackage().getName());
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(new File("D:\\cts2\\jaxbtest\\src\\main\\xsd\\schema1.xsd"));
    Marshaller marshaller = jaxbContext.createMarshaller();
    ObjectFactory of = new ObjectFactory();
    marshaller.setSchema(schema);
    Main main = new Main();
    Child1 child1 = new Child1();

    child1.setF1("test");

    main.setChild1(child1);

    final ValidationEventHandler validationEventHandler = marshaller.getEventHandler();
    marshaller.setEventHandler(new ValidationEventHandler() {
        @Override
        public boolean handleEvent(ValidationEvent event) {
            /*if(event.getLocator().getObject() instanceof Child1) {
                return true;
            } else {
                return validationEventHandler.handleEvent(event);
            }*/
            return validationEventHandler.handleEvent(event);
        }
    });

    System.out.println(marshaller.getEventHandler());
    marshaller.marshal(main, System.out);
}

2 个答案:

答案 0 :(得分:2)

架构没有定义不可能的情况。以下任何一个文档都应该(并且)对此模式有效:

<tns:Main xmlns:tns="urn:hl7-org:v3">
  <tns:child1><tns:f1>Hi, mom.</tns:f1></tns:child1>
</tns:Main>

<tns:Main xmlns:tns="urn:hl7-org:v3">
  <tns:child2><tns:f1>Hi, dad.</tns:f1></tns:child2>
</tns:Main>

但总的来说,模式定义一组不能同时满足的约束(或者,正如你所说的那样,定义一个不可能的XML词汇表)并不违反XSD规范。 )。要求XSD处理器检测所有不可满足约束的情况会给实施带来严重负担,并且不一定是任何人现在都知道如何满足的负担,更不用说满足可接受的性能。

但是,如果您不熟悉模式是可以满足的,那么您可能会认为模式意味着与它的意思不同的东西。由于您没有告诉我们任何相关信息,因此这里几乎没有人可以帮助您提高理解水平。祝好运!

答案 1 :(得分:2)

你的问题可能是什么

基于您问题中的相同代码,我假设您使用了类似以下的外部绑定文件来删除JAXBElement属性。

<jaxb:bindings
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
        jaxb:version="2.0"
        xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" 
        jaxb:extensionBindingPrefixes="xjc">

    <jaxb:globalBindings generateElementProperty="false">
        <xjc:simple />
    </jaxb:globalBindings>
</jaxb:bindings>

这将为您提供如下所示的Main类:

@XmlRootElement(name = "Main")
public class Main {

    @XmlElement(nillable = true)
    protected Child2 child2;
    @XmlElement(nillable = true)
    protected Child1 child1;

    ...

}

这将生成如下所示的XML,请注意child2child1元素的存在:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Main xmlns="urn:hl7-org:v3">
    <child2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:nil="true"/>
    <child1>
        <f1>test</f1>
    </child1>
</Main>

如何解决

您需要返回JAXBElement属性(以区分为xsi:nil="true"编组的值为null,或将缺少的节点作为选择的一部分)。这意味着您需要从外部绑定文件中删除generateElementProperty="false"。这将为您提供如下所示的Main类:

@XmlRootElement(name = "Main")
public class Main {

    @XmlElementRef(name = "child2", namespace = "urn:hl7-org:v3", type = JAXBElement.class, required = false)
    protected JAXBElement<Child2> child2;
    @XmlElementRef(name = "child1", namespace = "urn:hl7-org:v3", type = JAXBElement.class, required = false)
    protected JAXBElement<Child1> child1;

    ...

}

这将生成如下所示的XML,它可以正确验证:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Main xmlns="urn:hl7-org:v3">
    <child1>
        <f1>test</f1>
    </child1>
</Main>