#spring #spring-boot #jaxb #spring-batch #stax
#spring #spring-boot #jaxb #spring-batch #stax
Вопрос:
Я пытаюсь прочитать некорневые элементы из XML-файла с помощью Spring Batch.
Конфигурация пакета, которую я использую, содержит:
- a
StaxEventItemReader
, настроенный для чтения<dependency>
элементов Jaxb2Marshaller
привязка к классам, созданным JAXB
Как мне настроить StAX или JAXB для анализа некорневых элементов как отдельных элементов пакета Spring?
Например, допустим, мне нужно обработать <dependency>
элементы из Maven POM:
<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 «, local:»зависимость»). Ожидаемые элементы <{http://maven.apache.org/POM/4.0.0 }проект>
Чего мне не хватает?
Ответ №1:
Я нашел решение: мне нужно было позвонить 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;
}
Ответ №2:
Pom определяет пользовательское пространство xmlns="http://maven.apache.org/POM/4.0.0"
имен, поэтому вам нужно добавить к нему префикс имени корневого элемента фрагмента в определении компонента вашего читателя:
@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();
}
Комментарии:
1. К сожалению, это изменение не возымело никакого эффекта: я продолжаю получать ту же ошибку. Я считаю, что это не проблема с пространством имен, поскольку в сообщении об ошибке указано правильное пространство имен.