问题
I made earlier XSD+WSDL for a WS that is implemented by a customer. We implement the client. I have type like this in WS Create-operation:
<xs:complexType name="tWorkCreate">
<xs:sequence>
<xs:element ref="plan:workkey" />
<xs:element ref="plan:workdata" />
</xs:sequence>
</xs:complexType>
Now I would like to use the same type for new Update-operation, but naming is wrong. So I plan to do like this:
<xs:complexType name="tWorkSet">
<xs:sequence>
<xs:element ref="plan:workkey" />
<xs:element ref="plan:workdata" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="tWorkCreate">
<xs:complexContent>
<xs:extension base="tWorkSet">
<xs:sequence>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
and use tWorkSet
directly for Update
operation (tWorkCreate
operation would be the same). The existing customer does not need (and is not implementing) Update
. The reason for not duplicating the type is e.g that we could handle both Update
and Create
similarly in code. So is it better just to duplicate the type or is this extension scenario sensible?
回答1:
Yes, refactoring type definitions in this manner is a good idea and is backward compatible1. All of the same XML documents that were valid before the type refactoring will be valid after the refactoring. In fact, it's better than backward compatible because exactly the same set of XML documents that were valid before the change will be valid after the change.
1Assuming that clients have no direct dependencies against the type names themselves such as via JAXB bindings or xsi:type
use in XML doc instances. [Thanks to Petru Gardea.]
回答2:
Backward compatibility is very tricky when applied to XSD. A schema may be used in so many ways; without a solid understanding of boundaries, it is just a guess. For example, in general it is wrong to claim that changing a type name is backward compatible; what if someone uses xsi:type in their valid XML?
Creating type hierarchies should also be carefully planned. As with most mainstream OO languages today, you can only extend from one type.
In your case, you seem concerned about reuse; then maybe the safest might be to rather reuse by creating a group, which is then referenced by your type as needed. Of course, "safest" depends on the boundaries you define. For JAXB, .NET, etc. groups are supported and by default they are inlined - i.e. they have no footprint whatsoever in terms of XML, and generated code.
<xs:group name="tWorkSet">
<xs:sequence>
<xs:element ref="plan:workkey"/>
<xs:element ref="plan:workdata"/>
</xs:sequence>
</xs:group>
<xs:complexType name="tWorkCreate">
<xs:group ref="tWorkSet"/>
</xs:complexType>
来源:https://stackoverflow.com/questions/35479469/is-modifying-existing-xsd-type-by-extending-it-from-exact-same-type-backward-com