Hallo, ich habe ein Problem mit der Validierung mit JAXB2 ... leider habe ich schon extrem viel Zeit damit verloren und wäre sehr froh wenn mir hier jemand helfen könnte... ;(
Und zwar habe ich folgendes xsd:
[XML]
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Bookshop" xmlns:tns="http://www.example.org/Bookshop"
elementFormDefault="qualified">
<complexType name="creditCard">
<sequence>
<element name="number" type="string"></element>
<element name="expiringYear">
<simpleType>
<restriction base="int">
<pattern value="20[0-9][0-9]"></pattern>
</restriction>
</simpleType>
</element>
<element name="expiringMonth">
<simpleType>
<restriction base="int">
<minInclusive value="1"></minInclusive>
<maxInclusive value="12"></maxInclusive>
<pattern value="[1-9]?[0-9]"></pattern>
</restriction>
</simpleType>
</element>
<element name="owner" type="string"></element>
</sequence>
</complexType>
</schema>
[/XML]
Wenn ich mit XMLBeans 2.5.0 die Klassen aus dem Schema generieren lasse, sieht der Code zur Validierung wie folgt aus:
Dies ist sehr einfach und funktioniert auch einwandfrei. Die Ausgabe (d.h. so wie XMLBeans das XML intern darstellt) sieht so aus:
[XML]<xml-fragment>
<book:number xmlns:book="http://www.example.org/Bookshop">1234-5678-9000-0000</book:number>
<book:expiringYear xmlns:book="http://www.example.org/Bookshop">2113</book:expiringYear>
<book:expiringMonth xmlns:book="http://www.example.org/Bookshop">1</book:expiringMonth>
<bookwner xmlns:book="http://www.example.org/Bookshop">Homer Simpson</bookwner>
</xml-fragment>[/XML]
Es scheint also das XMLBeans hier einfach ein root-element hinzufügt und das ganze dann auch korrekt validieren kann. Der Test schlägt auch fehl weil 2113 bei expiringYear steht und nicht wie das Pattern im Schema verlangt etwas wie 2013.
Nun müssten wir das ganze noch mit JAXB2 irgendwie validieren können...und genau hier stehe ich an, d.h. es ist mir nicht möglich mit JAXB2 ein XML gegen das XSD validieren zu lassen. Egal was ich auch versuche, die Validierung schlägt immer fehl mit folgender Meldung:
Ein Beispiel wie ich die Validierung versucht habe durchzuführen sieht wie folgt aus:
Und die Ausgabe von sw.toString() liefert folgendes Resultat:
[XML]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<creditCard xmlns="http://www.example.org/Bookshop">
<number>1234-5678-9000-0000</number>
<expiringYear>2113</expiringYear>
<expiringMonth>1</expiringMonth>
<owner>Homer Simpson</owner>
</creditCard>
[/XML]
Kann mir jemand einen Tipp geben wie und ob es überhaupt möglich ist ein solches XML ohne wirkliches root-element mithilfe von JAXB2 zu validieren?!
Und zwar habe ich folgendes xsd:
[XML]
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Bookshop" xmlns:tns="http://www.example.org/Bookshop"
elementFormDefault="qualified">
<complexType name="creditCard">
<sequence>
<element name="number" type="string"></element>
<element name="expiringYear">
<simpleType>
<restriction base="int">
<pattern value="20[0-9][0-9]"></pattern>
</restriction>
</simpleType>
</element>
<element name="expiringMonth">
<simpleType>
<restriction base="int">
<minInclusive value="1"></minInclusive>
<maxInclusive value="12"></maxInclusive>
<pattern value="[1-9]?[0-9]"></pattern>
</restriction>
</simpleType>
</element>
<element name="owner" type="string"></element>
</sequence>
</complexType>
</schema>
[/XML]
Wenn ich mit XMLBeans 2.5.0 die Klassen aus dem Schema generieren lasse, sieht der Code zur Validierung wie folgt aus:
Java:
import java.io.IOException;
import java.io.StringWriter;
import org.example.bookshop.CreditCard;
import org.junit.Assert;
import org.junit.Test;
public class XMLBeansValidationTest {
@Test
public void testValidation() {
CreditCard creditCard = CreditCard.Factory.newInstance();
creditCard.setExpiringMonth(1);
creditCard.setExpiringYear(2113);
creditCard.setNumber("1234-5678-9000-0000");
creditCard.setOwner("Homer Simpson");
StringWriter sw = new StringWriter();
try {
creditCard.save(sw);
} catch (IOException e) {
e.printStackTrace();
Assert.fail();
}
System.out.println(sw.toString());
boolean isCreditCardValid = creditCard.validate();
Assert.assertTrue(isCreditCardValid);
}
}
Dies ist sehr einfach und funktioniert auch einwandfrei. Die Ausgabe (d.h. so wie XMLBeans das XML intern darstellt) sieht so aus:
[XML]<xml-fragment>
<book:number xmlns:book="http://www.example.org/Bookshop">1234-5678-9000-0000</book:number>
<book:expiringYear xmlns:book="http://www.example.org/Bookshop">2113</book:expiringYear>
<book:expiringMonth xmlns:book="http://www.example.org/Bookshop">1</book:expiringMonth>
<bookwner xmlns:book="http://www.example.org/Bookshop">Homer Simpson</bookwner>
</xml-fragment>[/XML]
Es scheint also das XMLBeans hier einfach ein root-element hinzufügt und das ganze dann auch korrekt validieren kann. Der Test schlägt auch fehl weil 2113 bei expiringYear steht und nicht wie das Pattern im Schema verlangt etwas wie 2013.
Nun müssten wir das ganze noch mit JAXB2 irgendwie validieren können...und genau hier stehe ich an, d.h. es ist mir nicht möglich mit JAXB2 ein XML gegen das XSD validieren zu lassen. Egal was ich auch versuche, die Validierung schlägt immer fehl mit folgender Meldung:
Java:
[org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'creditCard'.]
Ein Beispiel wie ich die Validierung versucht habe durchzuführen sieht wie folgt aus:
Java:
import java.io.IOException;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.util.JAXBSource;
import javax.xml.namespace.QName;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.example.bookshop.CreditCard;
import org.example.bookshop.ObjectFactory;
import org.junit.Assert;
import org.junit.Test;
import org.xml.sax.SAXException;
public class JAXB2ValidationTest {
@Test
public void testValidation() {
ObjectFactory of = new ObjectFactory();
CreditCard creditCard = of.createCreditCard();
creditCard.setExpiringMonth(1);
creditCard.setExpiringYear(2113);
creditCard.setNumber("1234-5678-9000-0000");
creditCard.setOwner("Homer Simpson");
try {
JAXBContext jc = JAXBContext.newInstance("org.example.bookshop");
SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(ClassLoader.getSystemResource("bookshop.xsd"));
Validator v = schema.newValidator();
JAXBElement<CreditCard> jaxbElementCreditCard = new JAXBElement<CreditCard>(new QName("http://www.example.org/Bookshop",
"creditCard"), CreditCard.class, creditCard);
StringWriter sw = new StringWriter();
Marshaller m = jc.createMarshaller();
m.marshal(jaxbElementCreditCard, sw);
System.out.println(sw.toString());
v.validate(new JAXBSource(jc, jaxbElementCreditCard));
} catch (JAXBException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
} catch (SAXException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
}
Und die Ausgabe von sw.toString() liefert folgendes Resultat:
[XML]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<creditCard xmlns="http://www.example.org/Bookshop">
<number>1234-5678-9000-0000</number>
<expiringYear>2113</expiringYear>
<expiringMonth>1</expiringMonth>
<owner>Homer Simpson</owner>
</creditCard>
[/XML]
Kann mir jemand einen Tipp geben wie und ob es überhaupt möglich ist ein solches XML ohne wirkliches root-element mithilfe von JAXB2 zu validieren?!