jackson-dataformat-xmlを使ってXMLをデシリアライズ
やりたいこと
前回ダウンロードした都道府県指定文化財データを全件ElasticSearchに登録したい。 その中で、jackson-dataformat-xmlを使ってXMLをJavaBeansにデシリアライズする。
準備
pom.xmlに以下を追記する。
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.13.3</version> </dependency>
公式ドキュメント
https://github.com/FasterXML/jackson-dataformat-xml
Bean
@JsonIgnoreProperties(ignoreUnknown = true)
で、XMLをマッピングする際に、Bean側に対応するフィールドがなくてもエラーを無視できる。今回は自分が使用しないデータは読み捨てたかったので指定。@Data
はlombokのアノテーション。
@Data @JacksonXmlRootElement(localName = "Dataset") @JsonIgnoreProperties(ignoreUnknown = true) public class GisData { @JacksonXmlProperty(localName = "Point") @JacksonXmlElementWrapper(useWrapping = false) private List<Point> points; @JacksonXmlProperty(localName = "CulturalProperty") @JacksonXmlElementWrapper(useWrapping = false) private List<CulturalProperty> culturalProperties; @Data @JsonIgnoreProperties(ignoreUnknown = true) public static class Point { @JacksonXmlProperty(isAttribute = true) private String id; @JacksonXmlProperty private String pos; } @Data @JsonIgnoreProperties(ignoreUnknown = true) public static class CulturalProperty { @JacksonXmlProperty(localName = "position") private PositionHref positionHref; @JacksonXmlProperty private String prefectureCode; @JacksonXmlProperty private String administrativeAreaCode; @JacksonXmlProperty private String largeClassificationCode; @JacksonXmlProperty private String smallClassificationCode; @JacksonXmlProperty private String culturalPropertyName; @JacksonXmlProperty private String address; @JacksonXmlProperty private Long specifiedDate; @JacksonXmlProperty private String pointClassificationCode; } @Data @JsonIgnoreProperties(ignoreUnknown=true) public static class PositionHref { @JacksonXmlProperty(isAttribute = true) private String href; } }
デシリアライズするコード
ObjectMapper xmlMapper = new XmlMapper(); GisData gisData = xmlMapper.readValue(new File(INPUT_FILE), GisData.class);
Beanの作成で分からなくなったら
いきなりBeanにマッピングしようとして期待する結果が得られず、しばらく悪戦苦闘した。そんな時は一旦readTree()
でJsonNode
にデシリアライズ、さらにJsonNode
をwriteValue()
でシリアライズして中身を確認すると、一気に理解が進んだ。
ObjectMapper xmlMapper = new XmlMapper(); JsonNode jsonNode = xmlMapper.readTree(new File(INPUT_FILE)); objectMapper.writeValue(new File(OUTPUT_XML_FILE), jsonNode);