I need to extend an existing XML document with new elements without losing the ability to validate it against both the unchanged original schema and an extended schema defined by me.
For example, lets say I want to add Code
and Price
elements to an existing Book
document, as follows:
<aa:Book xmlns:aa="http://www.aa.com"
xmlns:bb="http://www.bb.com">
<aa:Title>Complete Works</aa:Title>
<aa:Author>Shakespeare</aa:Author>
<bb:Code>98</bb:Code>
<bb:Price>31.6</bb:Price>
</aa:Book>
The original schema (which I cannot change) would look something like this:
<xs:schema targetNamespace="http://www.aa.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.aa.com"
elementFormDefault="qualified">
<xs:element name="Book" type="Book--type" />
<xs:complexType name="Book--type">
<xs:sequence>
<xs:element name="Title" type="xs:string" />
<xs:element name="Author" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
How would I create a new schema that defines these new elements such that a SchemaSet
containing both these schemas can successfully validate the extended XML document above?
I've tried the following usual complex type extension pattern:
<xs:schema targetNamespace="http://www.bb.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.bb.com"
xmlns:aa="http://www.aa.com"
elementFormDefault="qualified">
<xs:import namespace="http://www.aa.com" />
<xs:complexType name="Book--type">
<xs:complexContent>
<xs:extension base="aa:Book--type">
<xs:sequence>
<xs:element name="Code" type="xs:int" />
<xs:element name="Price" type="xs:double" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
However this causes errors stating that the element aa:Book
doesn't define a child element bb:Code
, which makes total sense.
Is this even possible?
For reference, here is the code I'm using to validate the document:
var fail = new ValidationEventHandler((sender, e) => Debug.Fail(e.Message));
var schemaSet = new XmlSchemaSet();
schemaSet.Add(XmlSchema.Read(new StringReader(original), fail));
schemaSet.Add(XmlSchema.Read(new StringReader(extension), fail));
var settings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
Schemas = schemaSet
};
settings.ValidationEventHandler += fail;
using (var stream = File.OpenRead(fileName))
using (var reader = XmlReader.Create(stream, settings))
{
while (reader.Read()) {}
}