我使用eclipse链接(v2.5.1)动态JAXB将XML转换为JSON,反之亦然使用多个模式。在将JSON编组为XML时,我希望验证JSON(针对XSD),而动态Moxy无法验证生成的JSON并导致转发异常。
emp.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:emp="Employee:2:0" targetNamespace="Employee:2:0"
elementFormDefault="unqualified" attributeFormDefault="unqualified"
version="2.0">
<xsd:element name="searchManager" type="emp:SearchManager" />
<xsd:complexType name="SearchManager">
<xsd:sequence>
<xsd:element name="CompanyName" type="xsd:string" />
<xsd:element name="objects" type="emp:Employee" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Employee">
<xsd:complexContent>
<xsd:extension base="emp:Organization">
<xsd:sequence>
<xsd:element name="EmpId" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Projects">
<xsd:complexContent>
<xsd:extension base="emp:Organization"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Organization">
<xsd:annotation>
<xsd:documentation>Abstract base class </xsd:documentation>
</xsd:annotation>
</xsd:complexType>
</xsd:schema>
Manager.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="Manager:1:0" xmlns:emp="Employee:2:0"
xmlns:manager="Manager:1:0" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified" attributeFormDefault="unqualified"
version="1.0">
<!-- schema imports -->
<xs:import namespace="Employee:2:0" schemaLocation="emp.xsd" />
<xs:complexType name="Manager">
<xs:annotation>
<xs:documentation>
Definition of class Employee
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="emp:Employee">
<xs:sequence>
<xs:element name="teamSize" type="xsd:int" minOccurs="0" />
<xs:element name="project1" type="manager:Project1"
minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Project1">
<xs:complexContent>
<xs:extension base="manager:Developement">
<xs:sequence>
<xs:element name="type" type="xsd:int" minOccurs="0" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Developement">
<xs:annotation>
<xs:documentation>
Abstract base class for an Development
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="emp:Projects"/>
</xs:complexContent>
</xs:complexType>
</xs:schema>
sample.xml中
<emp:searchManager xmlns:emp="Employee:2:0"
xmlns:manager="Manager:1:0">
<CompanyName>Test</CompanyName>
<objects xmlns:ns2="Manager:1:0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:Manager">
<EmpId>123456</EmpId>
<teamSize>10</teamSize>
<project1>
<type>1</type>
</project1>
</objects>
</emp:searchManager>
要测试的驱动程序如下
public class XMLToJSON {
/**
* @param args
*/
public static void main(String[] args) {
FileInputStream xsdInputStream;
try {
xsdInputStream = new FileInputStream("Manager.xsd");
DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, new MyEntityResolver(), null, null);
FileInputStream xmlInputStream = new FileInputStream("sample.xml");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement<DynamicEntity> manager = (JAXBElement) unmarshaller.unmarshal(xmlInputStream);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//input xml to print
marshaller.marshal(manager, System.out);
Map namespaces = new HashMap();
namespaces.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
namespaces.put("Employee:2:0", "ns1");
namespaces.put("Manager:1:0", "ns2");
// XML to JSON
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
FileOutputStream jsonOutputStream = new FileOutputStream("sample.json");
marshaller.marshal(manager, jsonOutputStream);
marshaller.marshal(manager, System.out);
//JSON to XML
JAXBUnmarshaller jsonUnmarshaller = jaxbContext.createUnmarshaller();
jsonUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaces);
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, true);
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX, "@");
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("Manager.xsd"));
jsonUnmarshaller.setSchema(schema);
StreamSource json = new StreamSource("sample.json");
JAXBElement<DynamicEntity> myroot = (JAXBElement) jsonUnmarshaller.unmarshal(json);
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
m.marshal(myroot, System.out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
生成的样本JSON
{
"ns1.searchManager" : {
"CompanyName" : "Test",
"objects" : [ {
"xsi.type" : "ns2.Manager",
"EmpId" : "123456",
"teamSize" : 10,
"project1" : [ {
"type" : 1
} ]
} ]
}
}
虽然看到了解组下面的例外
Exception in thread "main" java.lang.ClassCastException: org.eclipse.persistence.internal.oxm.record.XMLReaderAdapter$ExtendedContentHandlerAdapter cannot be cast to org.eclipse.persistence.internal.oxm.record.UnmarshalRecord
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.isTextValue(JSONReader.java:454)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:350)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:244)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:430)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:299)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:166)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:140)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:778)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:666)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:593)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:287)
at XMLToJSON.main(XMLToJSON.java:74)
编辑:更正了生成的样本json
问题
目的是检查JSON是否符合XML模式。动态JAXB在解组时是否支持JSON验证?这是动态JAXB Moxy中的错误吗?
答案 0 :(得分:1)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
您正在尝试在2.5.1(和2.6.0)流中修复的以下问题。
从2013年9月11日开始的每晚版本的EclipseLink 2.5.1(和2.6.0)中可以从以下链接获得该修复程序:
架构验证和JSON解组
由于我们需要处理JSON文档,因此无法保证针对XML模式验证JSON输入。以下是获得ClassCastException
修正后您将获得的例外情况。
javax.xml.bind.UnmarshalException
- with linked exception:
[Exception [EclipseLink-25004] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred unmarshalling the document
Internal Exception: org.xml.sax.SAXParseException; cvc-complex-type.2.4.d: Invalid content was found starting with element 'teamSize'. No child element is expected at this point.]
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:980)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:290)
at forum18824990.XMLToJSON.main(XMLToJSON.java:63)
Caused by: Exception [EclipseLink-25004] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred unmarshalling the document
Internal Exception: org.xml.sax.SAXParseException; cvc-complex-type.2.4.d: Invalid content was found starting with element 'teamSize'. No child element is expected at this point.
at org.eclipse.persistence.exceptions.XMLMarshalException.unmarshalException(XMLMarshalException.java:115)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:144)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:784)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:666)
at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:566)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:287)
... 1 more
Caused by: org.xml.sax.SAXParseException; cvc-complex-type.2.4.d: Invalid content was found starting with element 'teamSize'. No child element is expected at this point.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:453)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3232)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1795)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:741)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:565)
at org.eclipse.persistence.internal.oxm.record.XMLReader$ValidatingContentHandler.startElement(XMLReader.java:431)
at org.eclipse.persistence.internal.oxm.record.XMLReaderAdapter$ExtendedContentHandlerAdapter.startElement(XMLReaderAdapter.java:178)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:302)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:436)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:418)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:244)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:436)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:303)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:166)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:140)
... 5 more