【问题标题】:How to collect all xml elements in a list?如何收集列表中的所有 xml 元素?
【发布时间】:2017-06-15 13:19:49
【问题描述】:

我正在使用jackson-dataformat-xml

我有以下课程:

public class CTHotel {
    @JacksonXmlProperty(localName = "basic-info")
    private HotelBaseInfo hotelBaseInfo;

    //other properties and getters and setters
}

public class HotelBaseInfo {
    @JacksonXmlProperty(localName = "hotel-name")
    private String hotelName;

    @JacksonXmlElementWrapper(localName = "hotel-amenities")
    private List<HotelAmenity> hotelAmenities;

    //other properties and getters/setters
}

public class HotelAmenity {
    private String category;
    private String description;

    @JacksonXmlElementWrapper(localName = "amenities")
    private List<String> amenities;

    //other properties and getters/setters
}

我的 XML 是这样的:

<hotels>
    <hotel>
        <basic-info>
            <hotel-name>Hotel XYZ</hotel-name>
            <hotel-amenities>
                <hotel-amenity>
                    <category>F&B</category>
                    <description>Random Text</description>
                    <amenities>
                        <amenity>Cafe</amenity>
                        <amenity>Bar</amenity>
                        <amenity>Rastaurant</amenity>
                    </amenities>
                </hotel-amenity>
                <hotel-amenity>
                ...
                </hotel-amenity>   
            </hotel-amenities>
        </basic-info>
    </hotel>
    <hotel>
    ...
    </hotel>
</hotels>

我的问题是,如何将amenities 映射为我的HotelAmenity 类中的字符串列表,如上所述?我应该在amenities 字段上使用什么注释?

Hotel 类的hotelAmenities 字段上的@JacksonXmlElementWrapper 注释工作正常。

映射时出现以下错误:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: java.io.StringReader@507bcc81; line: 3, column: 1039] (through reference chain: com.example.response.HotelSearchResponse["hotels"]->java.util.ArrayList[2]->com.example.response.CTHotel["basic-info"]->com.example.response.HotelBaseInfo["hotel-amenities"]->java.util.ArrayList[1]->com.example.response.HotelAmenity["amenities"]->java.util.ArrayList[9])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) ~[jackson-databind-2.6.5.jar:2.6.5]
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:857) ~[jackson-databind-2.6.5.jar:2.6.5]
...

【问题讨论】:

    标签: java spring spring-boot jackson-dataformat-xml


    【解决方案1】:

    这是代码,希望能回答您的问题:

    /**Class Hotels*/
    @JacksonXmlRootElement(localName = "hotels")
    public class Hotels {
    
        @JacksonXmlElementWrapper(useWrapping = false)
        private List<Hotel> hotel;
    
        //Other getters and setters
    }
    
    /**Class Hotel*/
    @JacksonXmlRootElement(localName = "hotel")
    public class Hotel {
        @JacksonXmlProperty(localName = "basic-info")
        private HotelBaseInfo hotelBaseInfo;
    
        //Other getters and setters
    }
    
    /**Class HotelBaseInfo*/
    public class HotelBaseInfo {
        @JacksonXmlProperty(localName = "hotel-name")
        private String hotelName;
    
        @JacksonXmlElementWrapper(localName = "hotel-amenities")
        private List<HotelAmenity> hotelAmenities;
    
        //Other getters and setters
    
    }
    
    /**Class HotelAmenity*/
    public class HotelAmenity {
        private String category;
        private String description;
    
        @JacksonXmlElementWrapper(localName = "amenities")
        private List<Amenities> amenity;
    
        static class Amenities {
            @JacksonXmlText
            private String value;
        }
    
        //Other getters and setters
    }
    

    【讨论】:

      【解决方案2】:

      这对我有用:

      public class JacksonXmlParsing {
      
      @JacksonXmlRootElement(localName = "hotels")
      static class HotelSearchResponse {
      
          @JacksonXmlElementWrapper(localName = "hotel")
          private List<CTHotel> hotels;
      
          //other properties and getters and setters
      }
      
      static class CTHotel {
      
          @JacksonXmlProperty(localName = "hotel-name")
          private String hotelName;
      
          @JacksonXmlElementWrapper(localName = "hotel-amenities")
          private List<HotelAmenity> hotelAmenities;
      
          //other properties and getters and setters
      }
      
      static class HotelAmenity {
          private String category;
          private String description;
      
          @JacksonXmlElementWrapper
          private List<String> amenities;
      
          //other properties and getters/setters
      }
      
          public static void main(String[] args) throws IOException {
              XmlMapper xmlMapper = new XmlMapper();
      
              File file = new File("./src/main/resources/file.xml");
              HotelSearchResponse response = xmlMapper.readValue(file, HotelSearchResponse.class);
              System.out.println(response);
          }
      
      }
      

      输出: HotelSearchResponse(hotels=[CTHotel(hotelName=Hotel XYZ, hotelAmenities=[HotelAmenity(category=F&amp;B, description=Random Text, amenities=[Cafe, Bar, Rastaurant])])])

      但是basic-info标签丢失了,我可以找出原因。

      【讨论】:

      • 我已经编辑了我的问题。事实证明,我最小化的问题并没有得到我想要的答案。请现在看看。我还提到了我遇到的错误。
      • @mantri 你只有这三个类吗?您能否提供您用于解析给定 xml 的代码?
      • 酒店列表再次包含在 HotelSearchResponse 类中。这就是我映射 xml 的方式:XmlMapper mapper = new XmlMapper();HotelSearchResponse hotelSearchResponse = mapper.readValue(xmlStr, HotelSearchResponse.class);
      • 对于@JacksonXmlElementWrapper(localName = "hotel"),您使用子标签的名称为localName,但对于@JacksonXmlElementWrapper(localName = "hotel-amenities"),您使用包装标签的名称为localName。为什么会这样?
      猜你喜欢
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多