【问题标题】:Processing non-root XML elements with Spring Batch StaxEventItemReader使用 Spring Batch StaxEventItemReader 处理非根 XML 元素
【发布时间】:2021-03-27 06:28:23
【问题描述】:

我正在尝试使用 Spring Batch 从 XML 文件中读取非根元素。

我使用的批处理配置包含:

  • StaxEventItemReader 配置为读取 <dependency> 元素
  • Jaxb2Marshaller 绑定到 JAXB 生成的类

如何配置 StAX 或 JAXB 以将非根元素解析为单个 Spring Batch 项?

例如,假设我需要处理来自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:意外元素(uri:“http://maven.apache.org/POM/4.0.0”,本地:“依赖”)。预期的元素是

我错过了什么?

【问题讨论】:

    标签: spring spring-boot jaxb spring-batch stax


    【解决方案1】:

    pom 定义了一个自定义命名空间xmlns="http://maven.apache.org/POM/4.0.0",因此您需要在阅读器的 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();
    }
    

    【讨论】:

    • 不幸的是,此更改没有效果:我不断收到相同的错误。我相信这不是命名空间问题,因为错误消息显示了正确的命名空间。
    【解决方案2】:

    我找到了解决方案:我需要调用 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多