将NMTOKENS解组为列表

时间:2018-06-07 18:35:12

标签: java jaxb

NMTOKENS类型是由空格字符分隔的NMTOKEN列表。问题是我无法将值解组为complexType的List

我使用JAXB创建了对象模型,A类型的生成源为内容List<Serializable>,而TestSimpleListList<String>

public class A {

    @XmlMixed
    protected List<Serializable> content;
    @XmlAttribute(name = "a", required = true)
    @XmlSchemaType(name = "anySimpleType")
    protected String a;

public class UseCase {

    @XmlList
    @XmlElement(name = "TestSimpleList", required = true)
    @XmlSchemaType(name = "NMTOKENS")
    protected List<String> testSimpleList;

编组按预期工作,因此如果我向内容添加多个值,这些值将被序列化为由空格字符分隔的字符串。但它不适用于解组,List<Serializable>只包含一个由空格字符分隔的String元素。

您可以使用以下架构和测试用例测试问题:

有效的XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<UseCase xmlns="urn:xxx/1">
    <TestSimpleList>a b</TestSimpleList>
    <TestComplexList a="a">a b</TestComplexList>
</UseCase>

相应的架构:

<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="urn:xxx/1"
        xmlns:a="urn:xxx/1"
        elementFormDefault="qualified"
        attributeFormDefault="unqualified">

    <element name="UseCase">
        <complexType>
            <sequence>
                <element name="TestSimpleList" type="a:SimpleList"></element>
                <element name="TestComplexList" type="a:ComplexList"></element>
            </sequence>
        </complexType>
    </element>

    <simpleType name="SimpleList">
        <restriction base="NMTOKENS"></restriction>
    </simpleType>

    <complexType name="ComplexList">
        <simpleContent>
            <restriction base="a:A">
                <simpleType>
                    <restriction base="NMTOKENS"/>
                </simpleType>
            </restriction>
        </simpleContent>
    </complexType>

    <complexType name="A" mixed="true">
        <attribute name="a" use="required"/>
    </complexType>

</schema>

JAXB绑定:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
        jaxb:extensionBindingPrefixes="xjc">
    <jaxb:globalBindings generateMixedExtensions="true"/>
    <jaxb:bindings scd="x-schema::a" xmlns:a="urn:xxx/1">
        <jaxb:schemaBindings>
            <jaxb:package name="com.example.demo.tools.domain"/>
        </jaxb:schemaBindings>
    </jaxb:bindings>
</jaxb:bindings>

测试用例:

package com.example.demo.tools;

import com.example.demo.tools.domain.ComplexList;
import com.example.demo.tools.domain.UseCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;

import static org.junit.Assert.assertEquals;

@RunWith(MockitoJUnitRunner.class)
public class JaxbTest {

    @Test
    public void marshall() throws JAXBException {
        JAXBContext contextObj = JAXBContext.newInstance(UseCase.class);

        Marshaller marshaller = contextObj.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        UseCase useCase = new UseCase();
        useCase.getTestSimpleList().add("a");
        useCase.getTestSimpleList().add("b");

        ComplexList complexList = new ComplexList();
        complexList.setA("a");
        complexList.getContent().add("a");
        complexList.getContent().add("b");
        useCase.setTestComplexList(complexList);

        StringWriter sw = new StringWriter();
        marshaller.marshal(useCase, sw);
        System.out.println("sw = " + sw);
    }

    @Test
    public void unmarshall() throws JAXBException {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                "<UseCase xmlns=\"urn:xxx/1\">" +
                "<TestSimpleList>a b</TestSimpleList>" +
                "<TestComplexList a=\"a\">a b</TestComplexList>" +
                "</UseCase>";

        JAXBContext contextObj = JAXBContext.newInstance(UseCase.class);
        Unmarshaller unmarshaller = contextObj.createUnmarshaller();
        UseCase useCase = (UseCase) unmarshaller.unmarshal(new StringReader(xml));
        assertEquals(2, useCase.getTestSimpleList().size());
        // The following assertion fails
        assertEquals(2, useCase.getTestComplexList().getContent().size());
    }
}

0 个答案:

没有答案