2

I have the XMLGregorianCalander for storing a month

@XmlElement(name = "Month")
@XmlSchemaType(name = "gMonth")
protected XMLGregorianCalendar month;

I get the following error when unmarshalling

XML validation error on response: cvc-datatype-valid.1.2.1: '--11--' is not a valid value for 'gMonth'.

From what i can tell the format expected would be '--11', i have found related issues https://issues.apache.org/jira/browse/XERCESJ-1342 but i do not know the solution to change the format of a gMonth

the gmonth in the xsd looks like:

<xs:element name="Month" type="xs:gMonth"/>

Has this issue been resloved or a workaround exist?

4

2 回答 2

2

You could use an XmlAdapter to handle this use case.

GMonthAdapter

package forum13872065;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.datatype.*;

public class GMonthAdapter extends XmlAdapter<String, XMLGregorianCalendar> {

    DatatypeFactory dtf;

    public GMonthAdapter() {
         try {
            dtf = DatatypeFactory.newInstance();
        } catch (DatatypeConfigurationException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public XMLGregorianCalendar unmarshal(String v) throws Exception {
        return dtf.newXMLGregorianCalendar(v);
    }

    @Override
    public String marshal(XMLGregorianCalendar v) throws Exception {
        String string = v.toXMLFormat();
        if(string.endsWith("--")) {
            return string.substring(0,4);
        }
        return string;
    }

}

Root

The @XmlJavaTypeAdapter annotation is used to reference the XmlAdapter.

package forum13872065;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.datatype.XMLGregorianCalendar;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElement(name = "Month")
    @XmlSchemaType(name = "gMonth")
    @XmlJavaTypeAdapter(GMonthAdapter.class)
    protected XMLGregorianCalendar month;

}

Demo

Below is some demo code to prove that everything works.

package forum13872065;

import javax.xml.bind.*;
import javax.xml.datatype.DatatypeFactory;

public class Demo {

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

        Root root = new Root();
        DatatypeFactory dtf = DatatypeFactory.newInstance();
        root.month = dtf.newXMLGregorianCalendar("--11");

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

}

Output

Below is the output from running the demo code.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <Month>--11</Month>
</root>
于 2012-12-14T11:25:14.987 回答
1

The correct format for a gMonth is indeed --mm, but there was an error in the original edition of the XSD 1.0 specification that gave it as --mm--. Unfortunately this error was repeated in many books and tutorials on XSD, and in some software products, before it was corrected. So use of this data type can still be troublesome today, even though the bug was officially fixed almost ten years ago.

于 2012-12-14T14:49:07.307 回答