我使用 Jibx CodeGen maven 插件从 xsd 文件生成 java 源和绑定。
我想在同一应用程序中维护多个版本的 xsd,因此我计划根据 XSD 的版本生成不同的目标包。
JBix 似乎根据 xsd 文件的名称空间生成 java 包。
IE。对于命名空间http://www.example.jibx.org/generated/v30/types
它生成包org.jibx.example.generated.v30.types
在 Maven 构建代码生成期间似乎可以工作并生成绑定文件,但在绑定阶段,它表示验证失败:
maven日志样本
Generating code for mapping org.jibx.example.generated.v30.bar.Bar
Generating code for mapping org.jibx.example.generated.v30.bar.SpecificBar
Generating code for mapping org.jibx.example.generated.v30.foo.Foo
Generating code for mapping org.jibx.example.generated.v30.foo.SpecificFoo
Generating code for mapping org.jibx.example.generated.v30.generic.Generic
Generating code for mapping org.jibx.example.generated.v31.bar.Bar
Generating code for mapping org.jibx.example.generated.v31.bar.SpecificBar
Generating code for mapping org.jibx.example.generated.v31.foo.Foo
Generating code for mapping org.jibx.example.generated.v31.foo.SpecificFoo
Generating code for mapping org.jibx.example.generated.v31.generic.Generic
Wrote 16 files
org.jibx.example.generated.v30.bar.Bar output file size is 4365 bytes
Verification failure on class org.jibx.example.generated.v30.bar.Bar:
VERIFIED_REJECTED
Repository.lookup() failed. FILE NOT FOUND?
Found 10 methods:
void marshal
void JiBX_binding_v30_marshal_1_0
org.jibx.example.generated.v30.bar.Bar JiBX_binding_v30_newinstance_1_0
org.jibx.example.generated.v30.bar.Bar JiBX_binding_v30_unmarshal_1_0
java.lang.String JiBX_getName
void setSpecific
org.jibx.example.generated.v30.bar.SpecificBar getSpecific
void setGeneric
org.jibx.example.generated.v30.generic.Generic getGeneric
void unmarshal
org.jibx.example.generated.v30.bar.SpecificBar output file size is 2056 bytes
Verification failure on class org.jibx.example.generated.v30.bar.SpecificBar:
VERIFIED_REJECTED
Repository.lookup() failed. FILE NOT FOUND?
Found 6 methods:
java.lang.String getLabel
void JiBX_binding_v30_marshal_1_0
boolean JiBX_binding_v30_test_1_0
org.jibx.example.generated.v30.bar.SpecificBar JiBX_binding_v30_newinstance_1_0
org.jibx.example.generated.v30.bar.SpecificBar JiBX_binding_v30_unmarshal_1_0
void setLabel
org.jibx.example.generated.v30.foo.Foo output file size is 4365 bytes
Verification failure on class org.jibx.example.generated.v30.foo.Foo:
VERIFIED_REJECTED
Repository.lookup() failed. FILE NOT FOUND?
pom.xml
<properties>
<junit.version>4.11</junit.version>
<jibx.version>1.2.4.3</jibx.version>
<jibx.codegen.version>1.2.4.3</jibx.codegen.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<build-helper-maven-plugin.version>1.9.1</build-helper-maven-plugin.version>
</properties>
<repositories>
<repository>
<id>sonatype</id>
<name>Sonatype Groups</name>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<build>
<pluginManagement>
<plugins>
<!-- ### Target JDK 1.6 ### -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- #### Cleaning up generated sources #### -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.6.1</version>
<configuration>
<filesets>
<fileset>
<directory>src-generated/src</directory>
<includes>
<include>**/*</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.jibx</groupId>
<artifactId>maven-jibx-plugin</artifactId>
<version>${jibx.codegen.version}</version>
<configuration>
<schemaLocation>src/main/config</schemaLocation>
<schemaBindingDirectory>src-generated/src</schemaBindingDirectory>
<baseBindingDirectory>src-generated/src</baseBindingDirectory>
<targetDirectory>src-generated/src</targetDirectory>
</configuration>
<executions>
<execution>
<!-- ### Generation of binding for versions 3.0 of XSD ### -->
<id>generate-java-code-from-schema-3.0</id>
<phase>generate-sources</phase>
<goals>
<goal>schema-codegen</goal>
</goals>
<configuration>
<schemaLocation>src/main/config</schemaLocation>
<schemaBindingDirectory>src-generated/src</schemaBindingDirectory>
<baseBindingDirectory>src-generated/src</baseBindingDirectory>
<targetDirectory>src-generated/src</targetDirectory>
<includeSchemas>
<includeSchema>types-3.0.xsd</includeSchema>
<includeSchema>generic-3.0.xsd</includeSchema>
<includeSchema>foo-3.0.xsd</includeSchema>
<includeSchema>bar-3.0.xsd</includeSchema>
</includeSchemas>
<options>
<binding-file-name>binding-v30.xml</binding-file-name>
</options>
</configuration>
</execution>
<execution>
<id>generate-java-code-from-schema-3.1</id>
<phase>generate-sources</phase>
<goals>
<goal>schema-codegen</goal>
</goals>
<configuration>
<schemaLocation>src/main/config</schemaLocation>
<schemaBindingDirectory>src-generated/src</schemaBindingDirectory>
<baseBindingDirectory>src-generated/src</baseBindingDirectory>
<targetDirectory>src-generated/src</targetDirectory>
<includeSchemas>
<includeSchema>types-3.1.xsd</includeSchema>
<includeSchema>generic-3.1.xsd</includeSchema>
<includeSchema>foo-3.1.xsd</includeSchema>
<includeSchema>bar-3.1.xsd</includeSchema>
</includeSchemas>
<options>
<binding-file-name>binding-v31.xml</binding-file-name>
</options>
</configuration>
</execution>
<execution>
<id>compile-binding</id>
<phase>process-classes</phase>
<goals>
<goal>bind</goal>
</goals>
<configuration>
<includes>
<include>binding-v30.xml</include>
<include>binding-v31.xml</include>
</includes>
<load>true</load>
<validate>true</validate>
<verbose>true</verbose>
<verify>true</verify>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build-helper-maven-plugin.version}</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src-generated/src</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
foo-3.0.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.jibx.org/generated/v30/foo"
xmlns="http://www.example.jibx.org/generated/v30/foo"
xmlns:dgr="http://www.example.jibx.org/generated/v30/generic"
xmlns:tdr="http://www.example.jibx.org/generated/v30/types"
elementFormDefault="unqualified" attributeFormDefault="unqualified">
<xs:import namespace="http://www.example.jibx.org/generated/v30/generic"
schemaLocation="generic-3.0.xsd" />
<xs:import namespace="http://www.example.jibx.org/generated/v30/types"
schemaLocation="types-3.0.xsd" />
<xs:element name="foo">
<xs:complexType>
<xs:annotation>
<xs:documentation><![CDATA[ Documentation with french accentuation : éàç]]></xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="generic" type="dgr:generic" />
<xs:element name="specific" type="specificFoo" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="specificFoo">
<xs:sequence>
<xs:element name="label" type="label">
<xs:annotation>
<xs:documentation>Label for Foo</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="dateFoo" type="tdr:dateDDMMYYYY" minOccurs="0">
<xs:annotation>
<xs:documentation>Date of Foo</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="label">
<xs:restriction base="xs:string">
<xs:minLength value="2" />
<xs:maxLength value="255" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
通用-3.0.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.jibx.org/generated/v30/generic"
xmlns="http://www.example.jibx.org/generated/v30/generic"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tdr="http://www.example.jibx.org/generated/v30/types" elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<xs:import namespace="http://www.example.jibx.org/generated/v30/types"
schemaLocation="types-3.0.xsd" />
<xs:complexType name="generic">
<xs:annotation>
<xs:documentation>Generic data</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="type" type="tdr:typeCode">
<xs:annotation>
<xs:documentation>Type for code</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="isValid" type="xs:boolean">
<xs:annotation>
<xs:documentation>Flag that tells generic data is valid</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
类型-3.0.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tdr="http://www.example.jibx.org/generated/v30/types"
targetNamespace="http://www.example.jibx.org/generated/v30/types" elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<xs:simpleType name="text">
<xs:annotation>
<xs:documentation>Text</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:simpleType name="typeCode">
<xs:annotation>
<xs:documentation>Text</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:simpleType name="dateDDMMYYYY">
<xs:annotation>
<xs:documentation>Date au with format : DD/MM/YYYY</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:length value="10" />
<xs:pattern value="[0-3][0-9]/[0-1][0-9]/(19|20)[0-9]{2}" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
这是生成的绑定(binding-v30.xml)
<binding xmlns:ns1="http://www.example.jibx.org/generated/v30/bar" xmlns:ns2="http://www.example.jibx.org/generated/v30/foo" xmlns:dgr="http://www.example.jibx.org/generated/v30/generic" name="binding_v30" package="org.jibx.example.generated.v30" trim-whitespace="true">
<namespace uri="http://www.example.jibx.org/generated/v30/bar" prefix="ns1"/>
<namespace uri="http://www.example.jibx.org/generated/v30/foo" prefix="ns2"/>
<mapping class="org.jibx.example.generated.v30.bar.Bar" name="bar" ns="http://www.example.jibx.org/generated/v30/bar">
<structure map-as="dgr:generic" get-method="getGeneric" set-method="setGeneric" name="generic"/>
<structure map-as="ns1:specificBar" get-method="getSpecific" set-method="setSpecific" name="specific"/>
</mapping>
<mapping abstract="true" type-name="ns1:specificBar" class="org.jibx.example.generated.v30.bar.SpecificBar">
<value style="element" name="label" get-method="getLabel" set-method="setLabel"/>
</mapping>
<mapping class="org.jibx.example.generated.v30.foo.Foo" name="foo" ns="http://www.example.jibx.org/generated/v30/foo">
<structure map-as="dgr:generic" get-method="getGeneric" set-method="setGeneric" name="generic"/>
<structure map-as="ns2:specificFoo" get-method="getSpecific" set-method="setSpecific" name="specific"/>
</mapping>
<mapping abstract="true" type-name="ns2:specificFoo" class="org.jibx.example.generated.v30.foo.SpecificFoo">
<value style="element" name="label" get-method="getLabel" set-method="setLabel"/>
<value style="element" name="dateFoo" get-method="getDateFoo" set-method="setDateFoo" usage="optional"/>
</mapping>
<mapping abstract="true" type-name="dgr:generic" class="org.jibx.example.generated.v30.generic.Generic">
<value style="element" name="type" get-method="getType" set-method="setType"/>
<value style="element" name="isValid" get-method="isIsValid" set-method="setIsValid"/>
</mapping>
</binding>
我编写了一个 Junit 测试,以确保 jibx 可以实例化我的绑定对象的工厂并针对它解组 xml 文件。
Junit 单元测试:FooTest.java
@Test
public void testFoo1()
{
IBindingFactory foo30Factory = null;
try
{
foo30Factory = BindingDirectory.getFactory("binding_v30", Foo.class);
}
catch (JiBXException e)
{
String l_msg = "Cannot create factory ";
LOGGER.error(l_msg, e);
Assert.fail(l_msg + e.getMessage());
}
IUnmarshallingContext unmarshmallingContext = null;
try
{
unmarshmallingContext = foo30Factory.createUnmarshallingContext();
}
catch (JiBXException e)
{
String l_msg = "Cannot create unmarshmalling context ";
LOGGER.error(l_msg, e);
Assert.fail(l_msg + e.getMessage());
}
String l_xmlFileToTest = "/xml/foo1.xml";
LOGGER.info("Loading file : " + l_xmlFileToTest);
InputStream in = this.getClass().getResourceAsStream(l_xmlFileToTest);
BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
Foo l_fooObtained = null;
try
{
l_fooObtained = (Foo) unmarshmallingContext.unmarshalDocument(buffer);
}
catch (JiBXException e)
{
String l_msg = "Cannot instanciate object for class " + Foo.class;
LOGGER.error(l_msg, e);
Assert.fail(l_msg + e.getMessage());
}
Assert.assertNotNull("l_coeaObtenu ne doit pas etre null", l_fooObtained);
}
foo1.xml
<?xml version="1.0" encoding="UTF-8" ?>
<foo>
<generic>
<type>12345</type>
<isValid>1</isValid>
</generic>
<specific>
<label>Label example</label>
<dateFoo>01/01/2015</dateFoo>
</specific>
</foo>
当我运行它时,我得到了这个堆栈跟踪:No unmarshaller for element "generic"
ERROR FooTest - Cannot instanciate object for class class org.jibx.example.generated.v30.foo.Foo
org.jibx.runtime.JiBXException: No unmarshaller for element "generic" (line 5, col 14)
at org.jibx.runtime.impl.UnmarshallingContext.unmarshalElement(UnmarshallingContext.java:2754)
at org.jibx.runtime.impl.UnmarshallingContext.unmarshalDocument(UnmarshallingContext.java:2914)
at org.jibx.example.generated.v30.bar.FooTest.testFoo1(FooTest.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)