【问题标题】:Simple XML deserializing different element types with the same name简单的 XML 反序列化具有相同名称的不同元素类型
【发布时间】:2017-02-07 00:30:23
【问题描述】:

我正在尝试用 Java 反序列化 XML 的 sn-p:

<anime id="16986">
    <info type="Picture" src="http://~.jpg" width="141" height="200">
        <img src="http://~" width="141" height="200"/>
        <img src="http://~" width="318" height="450"/>
    </info>
    <info type="Main title" lang="EN">Long Riders!</info>
    <info type="Alternative title" lang="JA">ろんぐらいだぁす!</info>
</anime>

我遇到的问题是info 元素可以有一个img 的内联列表,也可以只包含文本。我正在考虑在我的 AnimeHolder 类中将info 视为@Element,但我不能有重复的注释。我还想访问 info 的 lang 属性来检查它是 EN 还是 JP。

我正在使用这些类来保存反序列化的数据:

@Root(name="anime", strict=false)
public class AnimeHolder {

    @Attribute(name="id")
    private String ANNID;

    @ElementList(inline=true)
    private List<InfoHolder> infoList;

    public String getANNID() {
        return ANNID;
    }

    public List<InfoHolder> getInfoList() {
        return infoList;
    }
}

对于信息项:

@Root(name="info", strict = false)
public class InfoHolder {

    @ElementList(inline=true, required = false)
    private List<ImgHolder> imgList;

    @Attribute(name = "lang", required = false)
    private String language;

    public List<ImgHolder> getImgList() {
        return imgList;
    }
}

【问题讨论】:

  • 您可能需要将&lt;info&gt; 定义为具有“混合”内容并在代码中处理文本与&lt;img&gt; 元素,例如禁止同时拥有 text 和 &lt;img&gt;。请参阅“How to deal with JAXB ComplexType with MixedContent data?”。
  • 谢谢!这为我指明了正确的方向。发布我的解决方案。

标签: java xml xml-deserialization simple-framework


【解决方案1】:

通过 Andreas,我发现我需要研究处理混合内容。做一些搜索让我找到了这个solution,关于创建自定义Converter。在写了我自己的并发现它没有被调用之后,this 帮助解决了这个问题。这是我重新设计的InfoHolder 类和转换器:

@Root(name="info", strict = false)
@Convert(InfoHolder.InfoConverter.class)
public class InfoHolder {

    private String englishTitle;
    private String imageURL;

    static class InfoConverter implements Converter<InfoHolder> {
        @Override
        public InfoHolder read(InputNode node) throws Exception {
            String value = node.getValue();
            InfoHolder infoHolder = new InfoHolder();

            if (value == null){
                InputNode nextNode = node.getNext();
                while (nextNode != null){
                    String tag = nextNode.getName();

                    if (tag.equals("img") && nextNode.getAttribute("src") != null){
                        infoHolder.imageURL = nextNode.getAttribute("src").getValue();
                    }
                    nextNode= node.getNext();
                }
            } else {
                while (node != null){
                    if (node.getAttribute("lang") != null){
                        if (node.getAttribute("lang").getValue().equals("EN")){
                            infoHolder.englishTitle = value;
                            break;
                        }
                    }
                    node = node.getNext();
                }
            }

            return infoHolder;
        }

        @Override
        public void write(OutputNode node, InfoHolder value) throws Exception {

        }
    }
}

我还需要使用AnnotationStrategy 实例化SimpleXmlConverterFactorySerializer,如下所示:

SimpleXmlConverterFactory factory = SimpleXmlConverterFactory.create(new Persister(new AnnotationStrategy()));

使用自定义转换器暴露了 XML 节点,这让我可以确定 info 节点是否有 img 子节点,如果没有,则获取节点值本身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 2015-10-08
    • 1970-01-01
    相关资源
    最近更新 更多