【问题标题】:Unmarshal with JAXB使用 JAXB 解组
【发布时间】:2014-02-11 12:15:20
【问题描述】:

我需要将 XML 字符串解组到项目中已经存在的类中,但我不知道如何将 XML 的某个部分解组为对象列表。让我用一些代码解释一下:

我有这个 XML:

<user>
  <id>123</id>
  <name>John Doe</name>
  <vaddresses>
    <address>
      <street>Street XYZ</street>
    </address>
    <address>
      <street>Street ABC</street>
    </address>
  </vaddresses>
</user>

我有这些课程:

  • 用户
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "User", propOrder = {"id", "name", "addresses"})
public class User {

    @XmlElement
    private int id;

    @XmlElement
    private String name;

    @XmlElement
    private List<Address> addresses;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(List<Address> addresses) {
        this.addresses = addresses;
    }
  • 地址
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Address", propOrder = {"street"})
public class Address {

    @XmlElement
    private String street;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
}

当我尝试将 XML 解组到这些类中时,字段 idname 被正确处理,但 addresses:

  • 输出
User: 
    Id: 123
    Nome: John Doe
    Addresses: null

我该如何解决这个问题?是否有一些我可以使用的 JAXB 注释?如何?还是我需要创建某种类型的 XmlAdapter? (我试过这个但没有成功......)

【问题讨论】:

  • Java 代码中的 addresses 不应该是 vadresses 吗?

标签: java xml jaxb unmarshalling


【解决方案1】:

您可以利用@XmlElementWrapper 在您的集合周围添加分组元素:

@XmlElementWrapper(name="vaddresses")
@XmlElement(name="address")
private List<Address> addresses;

注意

您添加的注释过多。 JAXB 是异常配置,因此您只需要注释您希望 XML 表示与默认值不同的位置。

【讨论】:

    【解决方案2】:

    我认为您必须更改私有财产地址的类型:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "User", propOrder = {"id", "name", "vaddresses"})
    public class User {
    
        @XmlElement
        private int id;
    
        @XmlElement
        private String name;
    
        @XmlElement
        private VAddress vaddresses;
    
        //...
     }
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "VAddress", propOrder = {"addresses"})
    public class VAddress {
    
        @XmlElement
        private List<Address> addresses;
    
        //...
     }
    

    或许你也可以试试@XmlElementWrapper注解。

    问候,

    【讨论】:

      【解决方案3】:

      用户.java

      package generated;
      
      import java.util.ArrayList;
      import java.util.List;
      import javax.xml.bind.annotation.XmlAccessType;
      import javax.xml.bind.annotation.XmlAccessorType;
      import javax.xml.bind.annotation.XmlElement;
      import javax.xml.bind.annotation.XmlRootElement;
      import javax.xml.bind.annotation.XmlType;
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "", propOrder = {
          "id",
          "name",
          "vaddresses"
      })
      @XmlRootElement(name = "user")
      public class User {
      
          protected int id;
          @XmlElement(required = true)
          protected String name;
          @XmlElement(required = true)
          protected User.Vaddresses vaddresses;
      
          public int getId() {
              return id;
          }
      
      
          public void setId(int value) {
              this.id = value;
          }
      
          public String getName() {
              return name;
          }
      
      
          public void setName(String value) {
              this.name = value;
          }
      
      
          public User.Vaddresses getVaddresses() {
              return vaddresses;
          }
      
          public void setVaddresses(User.Vaddresses value) {
              this.vaddresses = value;
          }
      
      
          @XmlAccessorType(XmlAccessType.FIELD)
          @XmlType(name = "", propOrder = {
              "address"
          })
          public static class Vaddresses {
      
              @XmlElement(required = true)
              protected List<User.Vaddresses.Address> address;
      
              public List<User.Vaddresses.Address> getAddress() {
                  if (address == null) {
                      address = new ArrayList<User.Vaddresses.Address>();
                  }
                  return this.address;
              }
      
      
              @XmlAccessorType(XmlAccessType.FIELD)
              @XmlType(name = "", propOrder = {
                  "street"
              })
              public static class Address {
      
                  @XmlElement(required = true)
                  protected String street;
      
      
                  public String getStreet() {
                      return street;
                  }
      
                  public void setStreet(String value) {
                      this.street = value;
                  }
      
              }
      
          }
      
      }
      

      JaxBExample.java

      package generated;
      import generated.User.Vaddresses.Address;
      
      import java.io.File;
      
      import javax.xml.bind.JAXBContext;
      import javax.xml.bind.JAXBException;
      import javax.xml.bind.Unmarshaller;
      
      public class JAXBExample {
          public static void main(String[] args) {
      
           try {
      
              File file = new File("D:\\StackOverFlow\\JAXBTest\\file.xml");
              JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
      
              Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
              User user = (User) jaxbUnmarshaller.unmarshal(file);
              System.out.println("ID::"+user.getId());
              System.out.println("Name::"+user.getName());
              System.out.print("Addresses::");
              for(Address address:user.getVaddresses().getAddress())
              {
                  System.out.println(address.getStreet());
              }
      
      
            } catch (JAXBException e) {
              e.printStackTrace();
            }
      
          }
      }
      

      输出:--

      ID::123 名称::John Doe 地址::Street XYZ 街道ABC

      【讨论】:

      • 我之前已经从 WSDL/XSD 生成了带有 JAXB 注释的类,它们遵循这种类型的结构(内部类),但此时不能更改我的类结构。
      猜你喜欢
      • 2013-01-17
      • 2012-12-21
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 2014-04-07
      相关资源
      最近更新 更多