JAXB强制命名空间URI - 为什么它甚至在没有定义时会期望某些命名空间?

时间:2015-01-28 09:09:46

标签: java xml xml-parsing namespaces jaxb

在尝试解组XML文档时我很神秘:

意外元素(uri:“http://www.xxx/xsd/ems/batchreq”,local:“batchParams”)。预期元素为< {} msgCollection>,< {} batchParams>]

元素不应该带有命名空间 - 它没有在xml中,也没有在java类中,但似乎在解析它时,它获得了命名空间uri - 而对于更大的谜团,具有命名空间的元素似乎没有期待它。

为什么?

将命名空间添加到@XmlElement会有所帮助,但似乎必须为每个元素定义 - 这是不可接受的解决方案。为什么命名空间不会被子元素继承?

根类是:

@XmlRootElement(name = "batch", namespace = "http://www.xxx/xsd/ems/batchreq")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "batch", namespace = "http://www.xxx/xsd/ems/batchreq", propOrder = { "batchParams", "msgCollection" })
public class Batch {

    @XmlAttribute(required = true)
    private String batchName;


    @XmlElement(name = "batchParams", required = true)
    private BatchParams batchParams;

    @XmlElement(name = "msgCollection", required = true)
    private Msgs msgCollection;
...

违规成员班是:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "batchParams", namespace = "http://www.xxx/xsd/ems/batchreq", propOrder = { "msgCount", "dateCreated" })
public class BatchParams {

    @XmlElement()
    private Long msgCount;

    @XmlElement()
    private Date dateCreated;

    public Long getMsgCount() {
...

Xml文件是:

<?xml version="1.0" encoding="UTF-8"?>
<batch xmlns="http://www.xxx/xsd/ems/batchreq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xxx/xsd/ems/batchreq ./ems_msg_batchreq.xsd" batchName="d" msgType="ems_sendemsg_batchreq" sourceSystem="1">
  <batchParams>
    <msgCount>1</msgCount>
    <dateCreated>2014-12-03T12:00:00</dateCreated>
  </batchParams>
  <msgCollection xmlns="http://www.xxx/xsd/ems/req">
    <msg msgType="ems_sendemsg_msg" sourceSystem="1" dataSourceSystem="1">
...
    </msg>
  </msgCollection>
</batch>

1 个答案:

答案 0 :(得分:1)

  

元素不应该带有命名空间 - 它在xml中没有,   也不是在java类中,但似乎在解析时,它会得到   namespace uri - 对于更大的神秘,具有命名空间的元素   好像没想到它。

您问题中的XML将http://www.xxx/xsd/ems/batchreq声明为默认命名空间。这意味着XML中未分配给不同命名空间的每个元素都将属于该命名空间。

<?xml version="1.0" encoding="UTF-8"?>
<batch xmlns="http://www.xxx/xsd/ems/batchreq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xxx/xsd/ems/batchreq ./ems_msg_batchreq.xsd" batchName="d" msgType="ems_sendemsg_batchreq" sourceSystem="1">
  <batchParams>
    <msgCount>1</msgCount>
    <dateCreated>2014-12-03T12:00:00</dateCreated>
  </batchParams>
  <msgCollection xmlns="http://www.xxx/xsd/ems/req">
    <msg msgType="ems_sendemsg_msg" sourceSystem="1" dataSourceSystem="1">
...
    </msg>
  </msgCollection>
</batch>

  

将命名空间添加到@XmlElement会有所帮助,但似乎它会   必须为每一个元素定义 - 这是不可接受的   溶液

您可以使用包级别@XmlSchema注释来映射默认命名空间限定。这是一个名为package-info.java的源文件,只有下面显示的内容。您需要更改包名称以匹配您的域模型。

@XmlSchema(
    namespace = "http://www.xxx/xsd/ems/batchreq",
    elementFormDefault = XmlNsForm.QUALIFIED)
package example;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

  

为什么命名空间不会被子元素继承?

JAXB中的命名空间规范确实是继承的,而不是你尝试过的方式。

  1. 包级别@XmlSchema注释提供了一种方法,用于指定应该由与该包中的类和属性对应的所有元素继承的默认命名空间。
  2. 类型级别@XmlType注释提供了一种指定此类上所有属性继承的命名空间的方法。这超过了@XmlSchema注释中指定的命名空间信息。
  3. 最后,可以在@XmlRootElement@XmlElement注释(以及其他一些注释)上指定名称空间。此处指定的命名空间仅适用于该元素。
  4. 了解更多信息

    我在博客上写了更多关于此用例的内容: