【问题标题】:Java JAXB Marshalling the elements to the objects in inner classJava JAXB将元素编组到内部类中的对象
【发布时间】:2021-07-20 12:49:35
【问题描述】:

我尝试使用 JAXB 注释将 JSON 数据转换为 XML。我的JSON 有点像这样:

{
   "Employee": {
      "name": "Tanmay",
      "Email": "tanmaypatil@xyz.com",
      "Address": {
         "City": "Florida",
         "State": "Miami"
      }
   }
}

我想使用编组来创建如下所示的 XML: (请注意extension 标签在JSON 中不存在,但我需要在XML 中添加)

<Company>
    <Employee>
        <FirstName>Tanmay</FirstName>
        <extension>
            <Address>
                <City>Florida</City>
                <State>Miami</State>
            </Address>
        </extension>
    </Employee>
</Company>

我有以下课程:

我的主类实际上会读取 JSON 数据并将其编组为 XML。为了简单起见,我使用 Jackson 来读取 JSON 数据,我删除了该代码:

public class Main
{
    public static void main(String[] args) {
        JsonFactory jsonFactory = new JsonFactory();
        JsonParser jsonParser = jsonFactory.createParser(new File(Main.class.getClassLoader().getResource("InputEPCISEvents.json").toURI()));
        //I am using the JAKSON jsonParser to read the JSON file and automatically map it to the child classes 
        //Ommiting the JACKSON JsonParser code for simplicity purpose
        JAXBContext context = JAXBContext.newInstance(Employee.class);
        Marshaller mar = context.createMarshaller();
        mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        mar.marshal(eventInfo, System.out);
        System.out.println("-----------------");
    }
}

以下是我的父类,它将映射到传入的 JSON:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlTransient
public class Employee{
    
    private String name;
    private String email;
    private Address address;
    
    //getters and setters are ommited
    //Noargs and allargs constuctor ommited
    
}

以下是我的Address 班级:

@XmlRootElement(name = "Employee")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Extension", propOrder = { "name","email","city","state"})
private class Address extends Employee{
    
    @XmlElement(name = "extension")
    private Extension extension;
    
    public Extension getExtension() {
        extension.setCity(getCity());
        extension.setState(getState());
        return extension;
    }
    
    public Extension setExtension(Extension extension) {
        this.setCity(extension.getCity());
        this.setState(extension.getState());
        this.extension = extension;
    }
}

以下是我创建为Extension 标记的Extension 类不会出现在传入的JSON 中,但我需要在编组期间将其添加到XML

@XmlAccessorType(XmlAccessType.FIELD)
public class Extension{
    private String city;
    private String state;
    
    //getters and setters are ommited
    //Noargs and allargs constuctor ommited
}

我想知道如何使用JAXB 执行以下操作。我可以创建一些额外的类或修改现有的类,但我无法更改传入的 JSONXML,因为它们是标准格式。

  1. 如何将 address,city,state 从 JSON 映射到 Class 对象。如果元素存在于Address.class 中,那么它可以自动映射,但由于我想要XML 中的extension 标记,我已将它们移动到我的Extension.class,因此JAXB 无法识别它并且它没有映射到对象。

  2. 如何将额外的extension 标记添加到将在编组期间创建的XML。我们可以看到JSON 不包含extension 标签,但我需要它在XML 中。如果它的集合,那么我可以使用@XmlElementWrapper,但在我的情况下它不是集合。

我尝试了很多搜索,但找不到任何对我有帮助的东西。所以根据我的理解,我已经做了上面提到的事情。任何帮助或建议将不胜感激。

【问题讨论】:

    标签: java xml jaxb marshalling maven-jaxb2-plugin


    【解决方案1】:

    最后,我能够使用Moxy @XmlPath 做到这一点。如果您使用的是Moxy,那么您可以使用@XmlPath 并添加额外的标签,而不必创建任何额外的类。

    例如,在这种情况下,我不必创建 Extension.class,但我仍然可以将 extension 标记添加到我的 XML 中。 Moxy 是基于 JAXB 的实现。

    我花了很多时间试图弄清楚很多事情。因此,发布相同的内容可能对将来的某人有所帮助。

    1. 您可以找到如何配置Moxy from here。不用担心它很简单。

    2. 你可以找到如何使用@XmlPathfrom here.

    您只需几个非常简单的步骤即可在 XML 中为非收藏项目获取包装标签。此外,无需创建多个额外的类。

    【讨论】:

      【解决方案2】:

      我认为您必须在您的 JAXBContext 中注册 所有 使用的类

      JAXBContext context = JAXBContext.newInstance(Employee.class, Extension.class, ...)
      

      或者,您也可以传递所有类的“根”包:

      JAXBContext context = JAXBContext.newInstance("com.demo.beans")
      

      【讨论】:

      • 非常感谢您的回复。我实际上试过这个,但没有奏效。我通过传递没有任何区别的类名尝试了第一种方法。我无法传递包名称,因为 Extension.class 存在于其他一些 Maven 项目中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多