【问题标题】:Reuse JAXB classes for similar schemas为相似的模式重用 JAXB 类
【发布时间】:2014-04-15 08:10:25
【问题描述】:

我有两个相似的模式,对于某些元素,它们具有相同的结构,但在不同的命名空间下定义。在为第二个模式生成类时,有没有办法为第一个模式重用 JAXB 生成的类?我知道 jaxb 允许绑定自定义,但我无法确定同一组类是否可以同时与两个命名空间一起使用。更具体地说:

架构1

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns="ns1" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="ns1">
    <xs:element name="Document" type="Document"/>
    <xs:complexType name="Document">
        <xs:sequence>
            <xs:element name="Root1" type="Root1Type"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Root1Type">
        <xs:sequence>
            <xs:element name="Child" type="ChildType"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="ChildType">
        <xs:sequence>
            <xs:element maxOccurs="1" minOccurs="0" name="MndtId" type="Max35Text"/>
            <xs:element name="MndtReqId" type="Max35Text"/>
        </xs:sequence>
    </xs:complexType>
    <xs:simpleType name="Max35Text">
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="35"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

架构2

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns="ns2" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="ns2">
    <xs:element name="Document" type="Document"/>
    <xs:complexType name="Document">
        <xs:sequence>
            <xs:element name="Root2" type="Root2Type"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Root2Type">
        <xs:sequence>
            <xs:element name="Child" type="ChildType"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="ChildType">
        <xs:sequence>
            <xs:element maxOccurs="1" minOccurs="0" name="MndtId" type="Max35Text"/>
            <xs:element name="MndtReqId" type="Max35Text"/>
        </xs:sequence>
    </xs:complexType>
    <xs:simpleType name="Max35Text">
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="35"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

xjc 将为第一个模式生成:

ns1/ChildType.java
ns1/Document.java
ns1/ObjectFactory.java
ns1/Root1Type.java
ns1/package-info.java

第二个:

ns2/ChildType.java
ns2/Document.java
ns2/ObjectFactory.java
ns2/Root2Type.java
ns2/package-info.java

我想知道的是,在为第二个模式生成类时,是否可以重用为第一个模式生成的 ChildType。

谢谢

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    这适用于您有多个仅在目标命名空间不同的 XML 架构时。

    生成您的 Java 模型

    从 XML 模式之一(即目标命名空间 ns 的模式)生成您的模型。

    处理来自主要 XML 架构的 XML

    对于直接对应于用于生成 Java 模型的 XML 模式的任何 XML,您可以正常编组/解组它

    从辅助 XML 模式处理 XML

    解组

    当您处理与命名空间 ns2 的架构相对应的 XML 文档时,您可以在解组时应用 SAX XMLFilter,它看起来好像与命名空间 ns1 的架构相对应。

    import org.xml.sax.*;
    import org.xml.sax.helpers.XMLFilterImpl;
    
    public class NamespaceFilter extends XMLFilterImpl {
    
        private static final String NAMESPACE = "ns1";
    
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            super.endElement(NAMESPACE, localName, qName);
        }
    
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes atts) throws SAXException {
            super.startElement(NAMESPACE, localName, qName, atts);
        }
    
    }
    

    演示代码

    这里有一些示例代码演示了如何应用XMLFilter

    import javax.xml.bind.*;
    import javax.xml.parsers.*;
    import org.xml.sax.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            // Create the JAXBContext
            JAXBContext jc = JAXBContext.newInstance("ns1");
    
            // Create the XMLFilter
            XMLFilter filter = new NamespaceFilter();
    
            // Set the parent XMLReader on the XMLFilter
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();
            filter.setParent(xr);
    
            // Set UnmarshallerHandler as ContentHandler on XMLFilter
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            UnmarshallerHandler unmarshallerHandler = unmarshaller
                    .getUnmarshallerHandler();
            filter.setContentHandler(unmarshallerHandler);
    
            // Parse the XML
            InputSource xml = new InputSource("input.xml");
            filter.parse(xml);
            Object result = unmarshallerHandler.getResult();
        }
    
    }
    

    编组

    待定

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      相关资源
      最近更新 更多