我无法从另一个项目扩展 xsd 模式。
我在 jar 项目 (ModelBase:jar) 中有一个 basemodel.xsd,它还包含通过 maven-jaxb2-plugin 生成的类。 我正在尝试在另一个项目(测试)中扩展该模型,使用 basemodel.xsd 作为依赖项
这里设置:
模型库中的basemodel.xsd:jar
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:tnsBaseModel="h-spamfilter-p://it.test.base.model" xmlns:xs="h-spamfilter-p://www.w3.org/2001/XMLSchema" xmlns:jaxb="h-spamfilter-p://java.sun.com/xml/ns/jaxb" targetNamespace="h-spamfilter-p://it.test.base.model" version="1.0" jaxb:version="2.1">
<xs:complexType name="requestBase">
<xs:sequence>
<xs:element name="errorMSG" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
model2.xsd 在测试中:jar
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:tns="h-spamfilter-p://it.test.newmodel" xmlns:tnsBaseModel="h-spamfilter-p://it.test.base.model" xmlns:xs="h-spamfilter-p://www.w3.org/2001/XMLSchema" xmlns:jaxb="h-spamfilter-p://java.sun.com/xml/ns/jaxb"
xmlns:annox="h-spamfilter-p://annox.dev.java.net" targetNamespace="h-spamfilter-p://it.test.newmodel" version="1.0" jaxb:version="2.1"
jaxb:extensionBindingPrefixes="annox">
<xs:import namespace="h-spamfilter-p://it.test.base.model"/>
<xs:complexType name="testInfo">
<xs:complexContent>
<xs:extension base="tnsBaseModel:requestBase">
<xs:sequence>
<xs:element name="body" type="tns:other"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
请注意没有显式 schemaLocation 的导入。
测试:jar pom:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
<configuration>
<generateDirectory>${project.build.directory}/generated-sources/annotations/</generateDirectory>
<cleanPackageDirectories>true</cleanPackageDirectories>
<forceRegenerate>true</forceRegenerate>
<schemas>
<schema>
<fileset>
<directory>${project.basedir}/src/main/resources</directory>
<includes>
<include>model2.xsd</include>
</includes>
</fileset>
</schema>
<schema>
<dependencyResource>
<groupId>it.test</groupId>
<artifactId>ModelBase</artifactId>
<version>${modelbase.version}</version>
<resource>basemodel.xsd</resource>
</dependencyResource>
</schema>
</schemas>
</configuration>
</plugin>
mvn -X 输出:
...
[INFO] dependsURIs (resolved):[file:/Users/computer/Documents/eclipse-workspace/test/src/main/resource/catalog.cat, file:/Users/computer/Documents/eclipse-workspace/test/src/main/resources/model2.xsd, file:/Users/computer/Documents/eclipse-workspace/test/src/main/resources/model2.xsd, jar:file:/Users/computer/.m2/repository/it/test/ModelBase/trunk-SNAPSHOT/ModelBase-trunk-SNAPSHOT.jar!/basemodel.xsd, file:/Users/computer/Documents/eclipse-workspace/test/pom.xml]
[INFO] optionsConfiguration:OptionsConfiguration [specVersion=2.2
generateDirectory=/Users/computer/Documents/eclipse-workspace/test/target/generated-sources/annotations
generatePackage=null
schemaLanguage=null
grammars.systemIds=[file:/Users/computer/Documents/eclipse-workspace/test/src/main/resources/model2.xsd, file:/Users/computer/Documents/eclipse-workspace/test/src/main/resources/model2.xsd, maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd]
bindFiles.systemIds=[]
plugins=[]
readOnly=false
packageLevelAnnotations=true
noFileHeader=false
enableIntrospection=false
disableXmlSecurity=true
accessExternalSchema=all
accessExternalDTD=all
contentForWildcard=false
extension=true
strict=true
verbose=true
debugMode=false
arguments=[-episode, /Users/computer/Documents/eclipse-workspace/test/target/generated-sources/annotations/META-INF/sun-jaxb.episode]]
[INFO] The [forceRegenerate] switch is turned on, XJC will be executed.
[INFO] Parsing input schema(s)...
[DEBUG] Resolving publicId [null], systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd].
resolveSystem(maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd)
[DEBUG] Parent resolver has resolved publicId [null], systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd] to [null].
[DEBUG] Resolving systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd] as Maven dependency resource.
[DEBUG] Resolved dependency resource [Dependency {groupId=it.test, artifactId=ModelBase, version=trunk-SNAPSHOT, type=jar, classifier=null, resource=basemodel.xsd}] to resource URL [jar:file:/Users/computer/.m2/repository/it/test/ModelBase/trunk-SNAPSHOT/ModelBase-trunk-SNAPSHOT.jar!/basemodel.xsd].
[DEBUG] Resolved systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd] to [jar:file:/Users/computer/.m2/repository/it/test/ModelBase/trunk-SNAPSHOT/ModelBase-trunk-SNAPSHOT.jar!/basemodel.xsd].
[DEBUG] Resolving publicId [h-spamfilter-p://it.test.base.model], systemId [null].
resolvePublic(h-spamfilter-p://it.test.base.model,null)
[DEBUG] Parent resolver has resolved publicId [h-spamfilter-p://it.test.base.model], systemId [null] to [null].
[ERROR] Error while parsing schema(s).Location [ file:/Users/computer/Documents/eclipse-workspace/test/src/main/resources/model2.xsd{1007,50}].
org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'tnsBaseModel:requestBase' to a(n) 'type definition' component.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException (ErrorHandlerWrapper.java:203)
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:396)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr (XSDHandler.java:4154)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError (XSDHandler.java:4137)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl (XSDHandler.java:1684)
at
[DEBUG] Resolving publicId [null], systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd].
resolveSystem(maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd)
[DEBUG] Parent resolver has resolved publicId [null], systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd] to [null].
[DEBUG] Resolving systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd] as Maven dependency resource.
[DEBUG] Resolved dependency resource [Dependency {groupId=it.test, artifactId=ModelBase, version=trunk-SNAPSHOT, type=jar, classifier=null, resource=basemodel.xsd}] to resource URL [jar:file:/Users/computer/.m2/repository/it/test/ModelBase/trunk-SNAPSHOT/ModelBase-trunk-SNAPSHOT.jar!/basemodel.xsd].
[DEBUG] Resolved systemId [maven:it.test:ModelBase:jar::trunk-SNAPSHOT!/basemodel.xsd] to [jar:file:/Users/computer/.m2/repository/it/test/ModelBase/trunk-SNAPSHOT/ModelBase-trunk-SNAPSHOT.jar!/basemodel.xsd].
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.076 s
[INFO] Finished at: 2023-03-29T10:21:00+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.14.0:generate (default) on project test: Unable to parse input schema(s). Error messages should have been provided. -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.14.0:generate (default) on project test: Unable to parse input schema(s). Error messages should have been provided.
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:375)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] h-spamfilter-p://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
我明白了
Cannot resolve the name 'tnsBaseModel:requestBase' to a(n) 'type definition' component.
,
添加 schemaLocation="basemodel.xsd" 导致获得[WARNING] Error while parsing schema(s).Location [ file:/Users/computer/Documents/eclipse-workspace/test/src/main/resources/model2.xsd{5,94}]. org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'basemodel.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
HiSrc HigherJAXB Maven 插件 是 maven-jaxb2-plugin 的一个分支,可用于演示此 solution (zip)。该解决方案包括一个 catalog 和一个 episode 配置,用于从 basemodel.xsd 和 model2.xsd 生成 JAXB 类,其中第二个模式导入第一个模式以扩展名为
requestBase
的复杂类型并定义一个元素/类型名为testInfo
.
A catalog 是包含“映射”信息的逻辑结构。为了最佳地利用有关 XML 外部资源的信息,需要一些可互操作的方式将 XML 外部标识符中的信息映射到所需资源的 URI 引用。
episode 文件,通常是
,由 XJC(XML Schema to Java)编译器生成。它是一个架构 bindings 文件,将架构类型与 existing 类相关联。当您有一个由其他模式导入的 XML 模式时,它很有用,因为它可以防止重新生成模型。 XJC 将扫描 JARs*META-INF/sun-jaxb.episode*
,然后自动将它们用作绑定文件。*.episode files
这个解决方案(zip)是一个独立的多模块Maven项目。您可以使用以下方式运行测试:
mvn -Pall,test clean test
mvn -Ptest clean install
cd extend
mvn -Ptest clean test
mvn -Pexec clean compile exec:java
只需第一次执行即可演示解决方案,此output 显示测试结果。其他处决提供了更多见解,如下所示:
mvn -Pall,test clean test
此解决方案包含一个顶层POM 项目和两个子模块:
和base
。第一次执行的目标是使用 Maven reactorextend
、clean
compile
和test
all 三个项目。 注意: reactor 将所有模块保留在类路径上;因此,模块能够解析extend
模块,聪明.base
mvn -Ptest clean install
要解决
工件 outside 的反应器,您需要将工件安装到本地存储库中。 注意:名为base
的配置文件仅用于将SLF4J实现添加到其测试阶段的构建中。test
cd extend
更改为
子模块以在多模块反应器外部进行测试和执行。extend
mvn -Ptest clean test
使用
配置文件执行干净测试以进行 单元测试.test
mvn -Pexec clean compile exec:java
执行一个简单的 Java application 来演示此示例 TestInfo.xml 的解组。 注意:
配置文件将 simplelogger.properties 和 SLF4J implementation 添加到类路径中,仅用于此执行。exec
因为model2.xsd导入basemodel.xsd中定义的命名空间,需要一个catalog.xml使用MavenCatalogResolver解析物理位置。
model2.xsd
...
<xs:import namespace="h-spamfilter-p://it.test.base.model"/>
...
在这种情况下,
namespace
是目录publicId
的公共标识符。
catalog.xml
...
<public
publicId="h-spamfilter-p://it.test.base.model"
uri="maven:org.patrodyne.jvnet:hisrc-higherjaxb-sample-base-extend-base!/basemodel.xsd"
/>
...
目录将
publicId
解析为 uri
,即物理位置。在这种情况下,物理位置在 base
罐子内。
因为base模块生成并提供了
RequestBase
类,你需要配置extend模块来使用*META-INF/sun-jaxb.episode*
bindings来自base模块。
扩展/pom.xml
...
<plugin>
<groupId>org.patrodyne.jvnet</groupId>
<artifactId>hisrc-higherjaxb-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<episodes>
<episode>
<groupId>org.patrodyne.jvnet</groupId>
<artifactId>hisrc-higherjaxb-sample-base-extend-base</artifactId>
</episode>
</episodes>
<!-- Using catalogs to resolve schema URIs in strict mode is known to be problematic and may fail. -->
<strict>false</strict>
<catalog>src/main/resources/catalog.xml</catalog>
</configuration>
</execution>
</executions>
</plugin>
...
重要提示: 您必须配置插件以使用您的catalog.xml 文件!
多模块Maven项目生成这些JAXB类,其中
TestInfo.java
扩展RequestBase.java
:
base/target/generated-sources/xjc
├── h_spamfilter_p
│ └── it_test_base
│ ├── ObjectFactory.java
│ ├── package-info.java
│ └── RequestBase.java
└── META-INF
└── sun-jaxb.episode
extend/target/generated-sources/xjc
├── h_spamfilter_p
│ └── it_test
│ ├── ObjectFactory.java
│ ├── package-info.java
│ └── TestInfo.java
└── META-INF
└── sun-jaxb.episode
JUnit 测试类 RequestBaseTest 和 TestInfoTest,扫描示例文件并调用方法
checkSample(File sample)
将每个文件提供给测试人员。对于这个项目,一个JAXBContext
被创建并且样本路径中的每个文件被unmarshaled到一个base-extend
对象。成功后,base-extend
对象被 marshaled 用于记录和您的审查。