在java中检测XML'schema'

时间:2014-12-10 08:15:47

标签: java xml jaxb

我使用JAXB将XML消息(字符串)解组为POJO。现在可以接收不同类型的消息。每种消息都有不同的结构,并映射到不同的POJO。

e.g。 PaymentRequest包含金额和货币,PrintRequest包含文本和徽标

<PaymentRequest>
  <amount>1.0</amount>
  <currency>EUR</currency>
</PaymentRequest>

<PrintRequest>
  <text>Hello world!</text>
  <logo>stackoverflow.png</logo>
</PrintRequest>

确定收到哪种邮件的最佳方法或最佳做法是什么?

  • 我应该在邮件中添加一些内容,以便更容易识别字符串吗?如果是这样,我应该添加什么(schema,namespace,...)?

  • 我应该创建一条&#39;消息&#39; POJO是我可以收到的所有不同XML消息的联合吗?

  • ...

任何指针都表示赞赏。

1 个答案:

答案 0 :(得分:1)

为什么不解组然后检查解组消息的类型?

您可能需要构建一个包含多个软件包的JAXBContext才能生效。类似的东西:

JAXBContext context = JAXBContext.newInstance("com.acme.foo.payment:com.acme.foo.print");

上下文必须知道您(可能)想要解组的元素。

接下来,在您的架构中,您还可以在架构中使用substitution groups。由于PrintRequestPaymentRequest都是请求,您可能需要为它们定义一个抽象元素:

<xs:element name="AbstractRequest" type="base:AbstractRequestType" abstract="true"/>

然后您的PrintRequestPaymentRequest可以替换此元素:

<xs:element name="PaymentRequest" type="payment:PaymentRequestType" substititionGroup="base:AbstractRequest"/>

在您的请求/响应架构中,您可以使用AbstractRequest,然后PaymentRequest可以替换JAXBElement<? extends AbstractRequestType。当解组时,这将为您提供更多的类型安全性。你会知道你会得到一个QName并且只需要弄明白,这是哪种请求类型。这可以基于JAXBElement的{​​{1}}或instanceof的暴力来完成。一种更好的方法是使用访问者模式,但是编写它有点复杂。