为类似的模式重用JAXB类 [英] Reuse JAXB classes for similar schemas
问题描述
我有两个类似的模式,对于某些元素,它们具有相同的结构,但是在不同的名称空间下定义。在为第二个模式生成类时,有没有办法为第一个模式重用JAXB生成的类?我知道jaxb允许绑定自定义,但是我无法确定同一组类是否可以与两个名称空间一起使用同时。更具体地说:
I have two similar schemas which have, for some elements, identical structure, but are defined under different namespaces. Is there any way to reuse the JAXB generated classes for the first schema when generating classes for the second schema? I know jaxb allows for binding customization, but I haven't been able to find out whether the same set of classes can be used simultaneously with two namespaces. More specifically:
Schema1
<?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>
Schema2
<?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将为第一个架构生成:
xjc will generate for the first schema:
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生成第二个模式的类时的模式。
What I would like to know is whether I can reuse ChildType generated for the first schema when generating classes for the second schema.
谢谢
推荐答案
当你有多个只有目标名称空间不同的XML模式时,这将有效。
This will work for when you have multiple XML Schemas that only differ by the target namespace.
从其中一个XML模式生成模型(即目标名称空间 ns
。
Generate your model from one of the XML Schemas (i.e. the one with target namespace ns
.
对于任何直接对应于您用于生成Java模型的XML模式的XML,您可以对其进行编组/解组
For any XML that corresponds directly to the XML Schema that you used to generate the Java model you can marshal/unmarshal it nornally
您可以应用SAX XMLFilter
当您处理与具有命名空间 ns2
的模式对应的XML文档时解组时,它看起来好像对应于具有命名空间的模式 ns1
。
You can apply a SAX XMLFilter
when unmarshalling to that when you are processing an XML document that corresponds to the schema with namespace ns2
it appears as though it corresponds to the schema with namespace 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
。
Here is some sample code demonstrating how to apply the 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();
}
}
编组
TBD
Marshalling
TBD
这篇关于为类似的模式重用JAXB类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!