【问题标题】:XStream parse attributes and values at the same timeXStream 同时解析属性和值
【发布时间】:2021-03-08 18:40:23
【问题描述】:

我有以下 XML

<search ver="3.0">
    <loc id="ARBA0009" type="1">Buenos Aires, Argentina</loc>
    <loc id="BRXX1283" type="1">Buenos Aires, Brazil</loc>
    <loc id="ARDF0127" type="1">Aeroparque Buenos Aires, Argentina</loc>
    <loc id="MXJO0669" type="1">Concepcion De Buenos Aires, Mexico</loc>
    <loc id="MXPA1785" type="1">San Nicolas De Buenos Aires, Mexico</loc>
    <loc id="ARBA0005" type="1">Balcarce, Argentina</loc>
    <loc id="ARBA0008" type="1">Bragado, Argentina</loc>
    <loc id="ARBA0010" type="1">Campana, Argentina</loc>
    <loc id="ARBA0016" type="1">Chascomus, Argentina</loc>
    <loc id="ARBA0019" type="1">Chivilcoy, Argentina</loc>
</search>

还有一个城市类

public class City {

    private String  id;
    private Integer type;
    private String  name;

    // getters & setters...
}

我尝试了以下别名来解析 XML

xStream.alias("search", List.class);
xStream.alias("loc", City.class);
xStream.useAttributeFor("id", String.class);
xStream.useAttributeFor("type", Integer.class);

但是我不知道如何设置“loc”标签的值,如果我尝试在 XML 中转换 City 对象,我会得到

<search>
    <loc id="ARBA0001" type="1">
        <name>Buenos Aires</name>
    </loc>
</search>

当我真的需要这个时

<search>
    <loc id="ARBA0001" type="1">Buenos Aires</loc>
</search>

然后,如果我尝试将 XML 解析为 City 对象,我会得到带有空值的字段“名称”。

有人知道如何设置正确的别名来做到这一点吗?提前致谢。

【问题讨论】:

    标签: xml xstream


    【解决方案1】:

    我终于找到了解决方案,一个转换器解决了这个问题,这里是代码

    public class CityConverter implements Converter {
    
        public void marshal(Object value, HierarchicalStreamWriter writer, 
                                                                   MarshallingContext context) {
            City city = (City) value;
            writer.addAttribute("id", city.getId());
            writer.addAttribute("type", city.getType().toString());
            writer.setValue(city.getName());
        }
    
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
            City city = new City();
            city.setName(reader.getValue());
            city.setId(reader.getAttribute("id"));
            city.setType(reader.getAttribute("type"));
            return city;
        }
    
        public boolean canConvert(Class clazz) {
            return clazz.equals(City.class);
        }
    
    }
    

    在设置别名的部分,我还设置了 CityConverter

    xStream.registerConverter(new CityConverter());
    xStream.alias("search", List.class);
    xStream.alias("loc", City.class);
    

    一切正常:)

    【讨论】:

      【解决方案2】:

      我发布这个是希望它可以帮助其他人,因为我花了很长时间才找到它...... http://fahdshariff.blogspot.com/2011/12/using-xstream-to-map-single-element.html

      答案是使用@XStreamConverter - ToAttributedValueConverter

      @XStreamAlias("error")
      @XStreamConverter(value=ToAttributedValueConverter.class, strings={"message"})
      public class Error {
      
        String message;
      
        ...
      

      有许多有趣的转换器提供各种有用的功能... http://x-stream.github.io/converters.html

      【讨论】:

        【解决方案3】:

        XStream 看起来有点复杂,你可以在 JAXB 中执行以下操作:

        public class City { 
        
            @XmlAttribute private String  id; 
            @XmlAttribute private Integer type; 
            @XmlValue private String  name; 
        
            // getters & setters... 
        }
        

        【讨论】:

        【解决方案4】:
        @XStreamConverter(value= ToAttributedValueConverter.class, strings={"name"})
        public class City { 
        
            @XStreamAsAttribute @XStreamAlias("id") private String  id; 
            @XStreamAsAttribute @XStreamAlias("type") private Integer type; 
            private String  name; 
        
            // getters & setters... 
        }
        

        【讨论】:

          猜你喜欢
          • 2016-03-16
          • 2016-03-16
          • 1970-01-01
          • 1970-01-01
          • 2011-06-05
          • 2021-04-14
          • 1970-01-01
          • 2017-05-20
          • 1970-01-01
          相关资源
          最近更新 更多