JAXB能否区分同类型不同名称XML元素?Scala XSD绑定疑问
问题描述
处理XML时遇到设计不佳的XSD,不同元素名称映射到同一类型,示例XSD片段:
<xsd:element name="NVAnfangF" type="NVAnfang"/> <xsd:element name="NVAnfangS" type="NVAnfang"/> <xsd:element name="NVEndeF" type="NVEnde"/> <xsd:element name="NVEndeS" type="NVEnde"/>
在业务场景中,<NVAnfangF>和<NVAnfangS>对应相似但不同的对象,但使用scalaxb生成Scala类时,两者的区别被抹平,仅生成case class NVAnfang。
请问:能否通过Scala或Java标准库自动生成可区分NVAnfangF与NVAnfangS的绑定?比如JAXB能否配置识别元素名称?还是必须自行编写代码生成器区分后缀F和S?
解决方案
1. JAXB配置方案
可以通过JAXB的绑定自定义文件(binding.xml)让生成的Java类区分不同元素,再在Scala中复用这些类:
- 编写绑定文件,为每个元素生成专属类:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1"> <jaxb:bindings schemaLocation="your-schema.xsd"> <jaxb:bindings node="//xsd:element[@name='NVAnfangF']"> <jaxb:class name="NVAnfangF"/> </jaxb:bindings> <jaxb:bindings node="//xsd:element[@name='NVAnfangS']"> <jaxb:class name="NVAnfangS"/> </jaxb:bindings> <jaxb:bindings node="//xsd:element[@name='NVEndeF']"> <jaxb:class name="NVEndeF"/> </jaxb:bindings> <jaxb:bindings node="//xsd:element[@name='NVEndeS']"> <jaxb:class name="NVEndeS"/> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
- 使用
xjc工具时指定该绑定文件,生成的NVAnfangF、NVAnfangS等类会继承或包装原NVAnfang、NVEnde类型,既复用结构,又能明确区分元素来源。
2. Scalaxb自定义配置
Scalaxb支持通过scalaxb-bindings.xml自定义生成规则,直接生成区分元素的Scala case class:
- 在绑定文件中为每个元素指定专属类名:
<scalaxb:bindings xmlns:scalaxb="http://scalaxb.org/xmlns/2010/scalaxb"> <scalaxb:package name="your.package"> <scalaxb:element name="NVAnfangF" class="NVAnfangF"/> <scalaxb:element name="NVAnfangS" class="NVAnfangS"/> <scalaxb:element name="NVEndeF" class="NVEndeF"/> <scalaxb:element name="NVEndeS" class="NVEndeS"/> </scalaxb:package> </scalaxb:bindings>
- 运行scalaxb时指定该绑定文件,生成的每个case class会对应唯一元素名称,同时内部复用原类型的字段结构,无需手动编写重复代码。
3. 无需自行编写代码生成器
不管用JAXB还是scalaxb,都可以通过官方提供的绑定配置机制实现需求,不需要从头编写代码生成器。这类配置能自动关联元素名称与生成的类,既保留原类型的结构复用,又能在业务代码中明确区分不同元素对应的对象。
内容的提问来源于stack exchange,提问作者Anaphory
相关产品推荐
相关产品推荐

