使用 Jackson 解析 XML 时如何忽略特定节点

Posted

技术标签:

【中文标题】使用 Jackson 解析 XML 时如何忽略特定节点【英文标题】:How to ignore a specific node when parsing XML with Jackson 【发布时间】:2019-01-16 04:25:51 【问题描述】:

我想知道在使用 Jackson ML 模块解析 XML 时是否可以忽略一个或多个节点。

我希望能够解析这个 XML

<bundle>
  <id value="myBundleId"/>
  <meta>
    <profile value="http://myurl/profile1" />
    <profile value="http://myurl/profile2" />
    <tag>
      <system value="https://myurl/system" />
      <code value="myAppCode"/>
    </tag>
  </meta>
  <type value="message" />
</bundle>

进入这个 POJO 对象

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

import lombok.Data;

@Data
public class Bundle 

    @JacksonXmlElementWrapper(localName = "id")
    @JacksonXmlProperty(isAttribute = true, localName = "value")
    private String id;

    @JacksonXmlElementWrapper(localName = "type")
    @JacksonXmlProperty(isAttribute = true, localName = "value")
    private String type;

现在它不起作用,因为我认为注释 @JacksonXmlElementWrapper 仅适用于列表。

它还给了我以下错误消息:

java.lang.IllegalArgumentException:冲突的 setter 定义 属性“值”

【问题讨论】:

尝试将您的字段转换为属性并将其公开。 嗯,你到底是什么意思?我必须补充一点,不幸的是 XML 无法修改,因为它是由外部方提供的。 【参考方案1】:

如果您不介意使用不同的库,SimpleXml 默认会这样做:

public class Bundle 
    @XmlWrapperTag("id")
    @XmlName("value")
    @XmlAttribute
    private String id;

    @XmlWrapperTag("type")
    @XmlName("value")
    @XmlAttribute
    private String type;

然后序列化打印:

final SimpleXml simple = new SimpleXml();
final Bundle bundle = simple.fromXml(xml, Bundle.class);
System.out.println(bundle.id + " : " + bundle.type);

这将打印:

myBundleId : message

SimpleXml 在 Maven 中心

<dependency>
    <groupId>com.github.codemonstur</groupId>
    <artifactId>simplexml</artifactId>
    <version>1.5.5</version>
</dependency>

【讨论】:

【参考方案2】:

要绑定属性,您可以使用 @JsonProperty Jackson Annotations

【讨论】:

【参考方案3】:

尝试以下方法:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Bundle 
   ...

或者:

mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

【讨论】:

感谢您的建议帮助,因为它允许像我想要的那样忽略 标记。您是否还知道如何将我的 Java 对象属性 id 绑定到 XML 值 myBundleId 而无需创建名为 Id 的子类? @Fred 你可以试试@JsonProperty。但这超出了您原始问题的范围。请提出一个新问题并添加所有相关详细信息。 @Fred 如果我的回答解决了您当前的问题,请不要忘记更新接受它:)【参考方案4】:

如果我没记错的话,你可以在对象映射器上设置它,这样可以避免在不匹配的节点上抛出异常。

objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

【讨论】:

以上是关于使用 Jackson 解析 XML 时如何忽略特定节点的主要内容,如果未能解决你的问题,请参考以下文章

Springboot引用jackson-dataformat-xml后如何返回json

忽略 Jackson 序列化的特定字段

您如何全局设置 Jackson 以忽略 Spring 中的未知属性?

Jackson Faster XML:如何解析抽象类'孩子?混入?

JAVA - 使用 FasterXml.Jackson 将 XML 文件解析为 Map

定制 Jackson 解析器来完成对复杂格式 XML 的解析