如何在xmlID xmlIDREF JAXB中使用数字和空格

时间:2015-09-29 17:03:12

标签: java xml jaxb

我有以下课程:

   @XmlRootElement
   @XmlAccessorType(XmlAccessType.FIELD)
   public class Employee {

   @XmlAttribute
   @XmlID
   private String id;

   public String getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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

   public Employee getManager() {
      return manager;
   }

   public void setManager(Employee manager) {
     this.manager = manager;
   }

   public List<Employee> getReports() {
      return reports;
   }

   public void setReports(List<Employee> reports) {
     this.reports = reports;
   }

  @XmlAttribute
  private String name;

  @XmlIDREF
  private Employee manager;

  @XmlElement(name="report")
  @XmlIDREF
  private List<Employee> reports;

  public Employee() {
      reports = new ArrayList<Employee>();
  }
}

公司类:

  @XmlRootElement
  @XmlAccessorType(XmlAccessType.FIELD)
  public class Company {

  @XmlElement(name="employee")
  private List<Employee> employees;

  public Company() {
      employees = new ArrayList<Employee>();
  } 

  public List<Employee> getEmployees(){
      return employees;
  }
}

我的主要内容如下:

    Employee employee1 = new Employee();
    employee1.setId("1");
    employee1.setName("Jane Doe");
    company.getEmployees().add(employee1);

    Employee employee2 = new Employee();
    employee2.setId("2");
    employee2.setName("John Smith");
    employee2.setManager(employee1);
    employee1.getReports().add(employee2);
    company.getEmployees().add(employee2);

    Employee employee3 = new Employee();
    employee3.setId("3");
    employee3.setName("Anne Jones");
    employee3.setManager(employee1);
    employee1.getReports().add(employee3);
    company.getEmployees().add(employee3);

如果我这样做,它运行正常。但是,如果我创建以下架构,然后在main中添加架构,那么我会收到以下错误:

架构:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="company" type="company"/>

    <xs:complexType name="company">
    <xs:sequence>
    <xs:element name="employee" type="employee" minOccurs="0"  maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="employee">
    <xs:sequence>
      <xs:element name="manager" type="xs:IDREF" minOccurs="0"/>
      <xs:element name="report" type="xs:IDREF" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID"/>
    <xs:attribute name="name" type="xs:string"/>
  </xs:complexType>
</xs:schema>

收到错误:

线程中的异常&#34; main&#34; javax.xml.bind.MarshalException   - 链接异常: [org.xml.sax.SAXParseException:cvc-datatype-valid.1.2.1:&#39; 1&#39;不是&#39; NCName&#39;。的有效值。]

我知道这是因为NCName不能以数字开头并且有空格。但就我而言,id是一个数字。

我想知道: 1)为什么只有在我包含架构时才会发生这种情况? 2)解决方法是什么,是使用moxy的唯一方法

1 个答案:

答案 0 :(得分:2)

1)使用marshaller.setSchema(schema)设置XML Schema;打开对该XML Schema的验证,并且您知道全数字ID值无效。

2)您可以使用适配器。

在Employee.java中添加注释:

@XmlAttribute
@XmlID
@XmlJavaTypeAdapter(Adapter.class)
private String id;

你需要这个简单的课程:

public class Adapter extends XmlAdapter<String, String> {
  @Override
  public String marshal(String s) throws Exception {
    return "_" + s;
  }
  @Override
  public String unmarshal(String v) throws Exception {
    return v.substring(1);
  }
}

根据XML Schema,生成的XML将是正确的:

<company>
  <employee id="_1" name="Jane Doe">
    <report>_2</report>
    <report>_3</report>
  </employee>
  <employee id="_2" name="John Smith">
    <manager>_1</manager>
  </employee>
  <employee id="_3" name="Anne Jones">
    <manager>_1</manager>
  </employee>
</company>