【问题标题】:Generating attribute option in xml using JAXB使用 JAXB 在 xml 中生成属性选项
【发布时间】:2023-03-17 22:00:01
【问题描述】:

我必须在我的程序中使用 JAXB 生成以下 xml。

         <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <Employee empId="12345">
          <name>ABC</name>
          <address type="Residence">Bangalore</address>
         </Employee>

我必须使用 JAXB 生成上述 xml。 我的 Employee 类如下:

员工类

    package mypack;
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement (name = "Employee")
    public class Employee {
            private String name;
        private String address;
        private int empId;
        private String addressType;

        @XmlAttribute
        public int getEmpId() {
            return empId;
        }
        public void setEmpId(int empId) {
            this.empId = empId;
        }

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

        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }

        public String getType() {
            return addressType;
        }
        public void setType(String addressType) {
            this.addressType = addressType;
        }   
    }

我正在使用 JAXB 来编组对象。

Employee emp = new Employee();
            emp.setName("ABC");
            emp.setEmpId(12345);
                emp.setAddress("Bangalore");
                    emp.setType("Residence");
                    JAXBContext context = JAXBContext.newInstance(Employee.class);
            Marshaller marshaller = context.createMarshaller();
            marshaller.marshal(emp, System.out);

它不会生成所需的 xml。而是按如下方式生成 xml:

**Xml Being Generated**

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Employee empId="12345">
       <name>ABC</name>
       <address>Bangalore</address>
       <type>Residence</type>
    </Employee>

其实我不知道怎么注释type属性,这样我就会生成xml为&lt;address type="Resident"&gt;Bangalore&lt;/address&gt; 我的 Employee 类应该像上面那样吗?如果是,那么如何注释 type 属性,使其成为&lt;address&gt; 标签中的属性。

请帮帮我。

【问题讨论】:

  • 您是否考虑过创建模式并使用 XJC 来创建您的 java 类?在您的架构中,您可以设置所需的所有属性和值。
  • 如果我从 xml 生成 java 类,Schema 将很有用。但我的要求是我必须生成从 java 对象指定的 xml。我的意思是说 java 到 xml,而不是相反。而且我不必担心 xml,因为在我的情况下,xml 不需要具有架构。谢谢
  • 仅供参考,如果您朝任一方向前进,都可以使用模式。即使我不需要,我发现使用模式来定义 XML 的格式并让 XJC 为我创建适合 JaxB 的 Java 类也很有帮助。我发现这比自己编写 JaxB 更容易。但这只是我。
  • 我同意。但是我没有任何 xsd 文件,因此我可以使用它来生成 java 类。我其实什么都没有。我的要求是按照上面的格式生成 xml 文件。我该如何进行?再次感谢。
  • 这就是我的观点。创建一个 xsd 文件并让它创建 Java 类,而不是自己创建类。您可以选择,您可以手动创建类,也可以创建 xsd 并让 XJC 从 xsd 创建类。就个人而言,鉴于需要生成具有某种格式的 xml 文件,我宁愿花精力创建 xsd。

标签: java jaxb marshalling unmarshalling jaxb2


【解决方案1】:

注意:我是EclipseLink JAXB (MOXy) 的负责人,也是JAXB 2 (JSR-222) 专家组的成员。

对于这个用例,您可以使用 MOXy 的 @XmlPath 扩展:

@XmlPath("address/@type")
public String getType() {
    return addressType;
}

员工

package mypack;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name = "Employee")
public class Employee {

    private String name;
    private String address;
    private int empId;
    private String addressType;

    @XmlAttribute
    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @XmlPath("address/@type")
    public String getType() {
        return addressType;
    }

    public void setType(String addressType) {
        this.addressType = addressType;
    }
}

演示

package mypack;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Employee.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/mypack/input.xml");
        Employee employee = (Employee) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(employee, System.out);
    }

}

输入/输出

<?xml version="1.0" encoding="UTF-8"?>
<Employee empId="12345">
   <address type="Resident">Bangalore</address>
   <name>ABC</name>
</Employee>

更多信息


更新

如果您不想使用任何供应商特定的扩展,那么您可以引入第二个类来表示地址信息:

地址

package mypack;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;

public class Address {

    private String address;
    private String addressType;

    @XmlValue   
    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @XmlAttribute
    public String getType() {
        return addressType;
    }

    public void setType(String addressType) {
        this.addressType = addressType;
    }
}

员工

package mypack;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Employee")
public class Employee {

    private String name;
    private Address address;
    private int empId;

    @XmlAttribute
    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

【讨论】:

  • 我必须使用 JAXB 从 java 生成 xml。使用简单的 javax.xml.bind 包是否可以实现结果?我的意思是不使用任何其他库。
  • @Surya - 你能改变你的对象模型并引入第二个类来表示地址信息吗?
  • 是的,我可以。但是我的第二课应该怎么上?如果该属性是像上面的 这样的复杂类型,那么我可以轻松地继续使用它。但是给我带来问题的属性是输入
    标签,这是一个简单的标签(其中没有任何嵌套标签)。你能解释一下如何进行吗?
  • @Surya - 我已经用新模型的外观更新了我的答案。
  • 成功了。非常感谢。我想不到的主要标签是第二个模型类中的@XmlValue。无论如何,感谢您回答我所有的问题。我希望我们不能在不为此创建另一个模型类的情况下生成相同的 xml。我说的对吗?
猜你喜欢
  • 1970-01-01
  • 2018-06-24
  • 2013-10-17
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
相关资源
最近更新 更多