【问题标题】:XStream : node with attributes and text node in xstream 1.3.1?XStream:xstream 1.3.1 中具有属性和文本节点的节点?
【发布时间】:2014-06-27 13:26:15
【问题描述】:

我想用 XStream 将一个对象序列化为这种形式的 XML。

<node att="value">text</node>

这里的 * 中已经有一个解决方案: XStream : node with attributes and text node? 它对我不起作用,因为我仅限于 XStream 1.3.1。

我找到了

@XStreamConverter(value=ToAttributedValueConverter.class, strings={"content"}) 

它以一种简单的方式完全符合我的要求,但它在 XStream 1.3.1 中不可用。

1.3.1 版本的 XStream 有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: java xml xstream


    【解决方案1】:

    通过一些技巧可以实现。主要的 idia 是使用从 1.4.7 修改的 ToAttributedValueConverter

    1. ToAttributedValueConverter复制到你的包中
    2. UseAttributeForEnumMapper复制到你的包中
    3. 替换ToAttributedValueConverter#fieldIsEqual如下:

      private boolean fieldIsEqual(FastField field) {
          return valueField.getName().equals(field.getName())
                  && valueField.getDeclaringClass().getName()
                          .equals(field.getDeclaringClass().getName());
      }
      
    4. 替换UseAttributeForEnumMapper中的构造函数如下:

      public UseAttributeForEnumMapper(Mapper wrapped) {
          super(wrapped, null);
      }
      

    不能使用@XStreamConverter 注释,因为ToAttributedValueConverter 有一个需要一些额外信息的构造器,比如值字段。但是您可以交替使用XStream#registerConverter。所以你的班级必须看起来像:

        @XStreamAlias("node")
        public class Node {
            private String attr;
            private String content;
    
            public void setAttr(String attr) { this.attr = attr; }
            public String getAttr() { return attr; }
            public void setContent(String content) { this.content = content; }
            public String getContent() { return content; }
        }
    

    还有一个展示如何为此转换器配置 xstream 的示例:

        public static void main(String[] args) {
            final Node node = new Node();
            node.setAttr("value");
            node.setContent("text");
    
            final XStream xstream = new XStream();
            configureXStream(xstream);
    
            final String xml = xstream.toXML(node);
            System.out.println(xml);
    
            final Node node2 = (Node) xstream.fromXML(xml);
            System.out.println("attr: " + node2.getAttr());
            System.out.println("content: " + node2.getContent());
        }
    
        private static void configureXStream(final XStream xstream) {
            xstream.autodetectAnnotations(true);
            final Mapper mapper = xstream.getMapper();
            final ReflectionProvider reflectionProvider = xstream
                    .getReflectionProvider();
            final ConverterLookup lookup = xstream.getConverterLookup();
            final Converter converter = new ToAttributedValueConverter(Node.class,
                    mapper, reflectionProvider, lookup, "content");
            xstream.registerConverter(converter);
        }
    

    这个程序打印出来:

        <node attr="value">text</node>
        attr: value
        content: text
    

    【讨论】: