有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java简单XML反序列化同名的不同元素类型

我正在尝试用Java反序列化这段XML:

<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;
    }
}

共 (1) 个答案

  1. # 1 楼答案

    有了Andreas,我发现我需要研究如何处理混合内容。通过一些搜索,我找到了关于创建自定义Convertersolution。在写了我自己的并且发现它没有被调用之后,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 {
    
            }
        }
    }
    

    我还需要使用AnnotationStrategySerializer实例化一个SimpleXmlConverterFactory,如下所示:

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

    使用自定义转换器公开XML节点,这使我能够确定info节点是否有img子节点,如果没有,则获取节点值本身