使用 Spring Batch StaxEventItemReader 处理非根 XML 元素
Processing non-root XML elements with Spring Batch StaxEventItemReader
我正在尝试使用 Spring 批处理从 XML 文件中读取非根元素。
我使用的批量配置包含:
- a
StaxEventItemReader
配置为读取 <dependency>
个元素
- a
Jaxb2Marshaller
绑定到 JAXB 生成的 类
如何配置 StAX 或 JAXB 以将非根元素解析为单个 Spring 批处理项目?
例如,假设我需要处理来自 Maven POM:
的 <dependency>
个元素
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>
<dependency>...</dependency>
<dependency>...</dependency>
<dependency>...</dependency>
...
</dependencies>
</project>
使用以下代码(我只显示相关部分):
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Bean
public ItemReader<Dependency> reader(Jaxb2Marshaller marshaller) {
return new StaxEventItemReaderBuilder<Dependency>().name("itemReader")
.resource(inputFile)
.addFragmentRootElements("dependency")
.unmarshaller(marshaller)
.build();
}
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("org.apache.maven.pom._4_0");
return marshaller;
}
}
但我收到以下错误:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://maven.apache.org/POM/4.0.0", local:"dependency"). Expected elements are <{http://maven.apache.org/POM/4.0.0}project>
我错过了什么?
pom 定义了一个自定义命名空间 xmlns="http://maven.apache.org/POM/4.0.0"
,因此您需要在 reader 的 bean 定义中使用它作为片段根元素名称的前缀:
@Bean
public ItemReader<Dependency> reader(Jaxb2Marshaller marshaller) {
return new StaxEventItemReaderBuilder<Dependency>().name("itemReader")
.resource(inputFile)
.addFragmentRootElements("{http://maven.apache.org/POM/4.0.0}dependency")
.unmarshaller(marshaller)
.build();
}
我找到了一个解决方案:我需要调用 Jaxb2Marshaller.setMappedClass
来启用部分解组:
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("org.apache.maven.pom._4_0");
marshaller.setMappedClass(Dependency.class); // ADD THIS LINE
return marshaller;
}
我正在尝试使用 Spring 批处理从 XML 文件中读取非根元素。
我使用的批量配置包含:
- a
StaxEventItemReader
配置为读取<dependency>
个元素 - a
Jaxb2Marshaller
绑定到 JAXB 生成的 类
如何配置 StAX 或 JAXB 以将非根元素解析为单个 Spring 批处理项目?
例如,假设我需要处理来自 Maven POM:
的<dependency>
个元素
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>
<dependency>...</dependency>
<dependency>...</dependency>
<dependency>...</dependency>
...
</dependencies>
</project>
使用以下代码(我只显示相关部分):
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Bean
public ItemReader<Dependency> reader(Jaxb2Marshaller marshaller) {
return new StaxEventItemReaderBuilder<Dependency>().name("itemReader")
.resource(inputFile)
.addFragmentRootElements("dependency")
.unmarshaller(marshaller)
.build();
}
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("org.apache.maven.pom._4_0");
return marshaller;
}
}
但我收到以下错误:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://maven.apache.org/POM/4.0.0", local:"dependency"). Expected elements are <{http://maven.apache.org/POM/4.0.0}project>
我错过了什么?
pom 定义了一个自定义命名空间 xmlns="http://maven.apache.org/POM/4.0.0"
,因此您需要在 reader 的 bean 定义中使用它作为片段根元素名称的前缀:
@Bean
public ItemReader<Dependency> reader(Jaxb2Marshaller marshaller) {
return new StaxEventItemReaderBuilder<Dependency>().name("itemReader")
.resource(inputFile)
.addFragmentRootElements("{http://maven.apache.org/POM/4.0.0}dependency")
.unmarshaller(marshaller)
.build();
}
我找到了一个解决方案:我需要调用 Jaxb2Marshaller.setMappedClass
来启用部分解组:
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("org.apache.maven.pom._4_0");
marshaller.setMappedClass(Dependency.class); // ADD THIS LINE
return marshaller;
}