【问题标题】:Can JAXB initialize values in base classes?JAXB 可以在基类中初始化值吗?
【发布时间】:2012-01-11 12:18:58
【问题描述】:

我正在处理一个 Scala 项目,我们希望使用 XML 来通过 JAXB(不是 Spring)初始化我们的对象。我有一个层次结构,在子类中添加了更多数据成员。一个简单的示例如下所示:

class Animal
{
   string name
}

class Cat extends Animal
{
   int numLives
}

class Dog extends Animal
{
   bool hasSpots
}

我希望能够从如下所示的 XML 块初始化动物列表:

<Animals>
   <Cat>
      <name>Garfield</name>
      <numLives>9</numLives>
   </Cat>
   <Dog>
      <name>Odie</name>
      <hasSpots>false</hasSpots>
   </Dog>
</Animals>

我们将如何设置类中的注释来处理这个问题?

【问题讨论】:

    标签: java xml jaxb xml-parsing


    【解决方案1】:

    在这种情况下,我更喜欢创建 XSD 架构并从中生成代码,这样您就安全了。 但要回答你的问题,是的,你可以。注释是 XMLElement、XMLAttribute、XMLRootElement。

    【讨论】:

      【解决方案2】:

      对于本示例,您将需要使用 @XmlElementRef@XmlRootElement 注释。这对应于替换组的 XML 模式概念。这将允许您拥有一个按元素区分的继承层次结构中的对象列表。

      动物

      这将作为域模型的根对象。它有一个带有@XmlElementRef 注释的List 属性。这意味着它将根据 @XmlRootElement 注释的值匹配值。

      package forum8356849;
      
      import java.util.List;
      
      import javax.xml.bind.annotation.*;
      
      @XmlRootElement(name="Animals")
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlSeeAlso({Cat.class, Dog.class})
      public class Animals {
      
          @XmlElementRef
          private List<Animal> animals;
      }
      

      动物

      package forum8356849;
      
      import javax.xml.bind.annotation.*;
      
      @XmlAccessorType(XmlAccessType.FIELD)
      class Animal
      {
         String name;
      }
      

      我们将使用@XmlRootElement 注释来注释Cat 类。这与Animals 上的@XmlElementRef 注释一起使用。

      package forum8356849;
      
      import javax.xml.bind.annotation.*;
      
      @XmlRootElement(name="Cat")
      class Cat extends Animal
      {
         int numLives;
      }
      

      我们还将在Dog 类中添加一个@XmlRootElement 注释。

      package forum8356849;
      
      import javax.xml.bind.annotation.*;
      
      @XmlRootElement(name="Dog")
      class Dog extends Animal
      {
         boolean hasSpots;
      }
      

      演示

      您可以使用以下类来查看一切是否按预期工作。 input.xml 对应于您问题中提供的 XML。

      package forum8356849;
      
      import java.io.File;
      import javax.xml.bind.*;
      
      public class Demo {
      
          public static void main(String[] args) throws Exception {
              JAXBContext jc = JAXBContext.newInstance(Animals.class);
      
              Unmarshaller unmarshaller = jc.createUnmarshaller();
              File xml = new File("src/forum8356849/input.xml");
              Animals animals = (Animals) unmarshaller.unmarshal(xml);
      
              Marshaller marshaller = jc.createMarshaller();
              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
              marshaller.marshal(animals, System.out);
          }
      
      }
      

      更多信息

      【讨论】:

      • 谢谢!我试试看!
      • 啊,我遇到了一个小问题...我的应用程序需要支持插件,@XmlSeeAlso({Cat.class, Dog.class}) 意味着我需要在编译时了解我的后代。有什么办法吗?
      • @fbl - 您不需要使用 XmlSeeAlso,但 JAXBContext 确实需要了解子类。您可能会发现以下方法更合适:blog.bdoughan.com/2010/08/…
      猜你喜欢
      • 1970-01-01
      • 2012-01-16
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 2011-01-12
      • 1970-01-01
      相关资源
      最近更新 更多