I have an existing namespace that I cannot change. I need to add elements to a complex type such that the resulting XML looks like this:
Original XML:
<?xml version="1.0"?>
<Book xmlns="http://bookshop.com">
<Author>Frank Herbert</Author>
<Title>Dune</Title>
</Book>
New XML:
<?xml version="1.0"?>
<Book xmlns="http://bookshop.com"
xlmns:custom="http://custombookshop.com">
<Author>Frank Herbert</Author>
<Title>Dune</Title>
<custom:Publisher>Ace</custom:Publisher>
</Book>
I have requirements that the custom elements must appear as above with the namespace prefix, and that the complex type name must not change.
Here is the original XSD and the new XSD I've attempted using redefine. Will this work, or is there a better way to accomplish this? Thanks in advance for your advice.
Original XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://bookshop.com"
targetNamespace="bookshop.com">
<xs:complexType name="Book">
<xs:complexContent>
<xs:sequence>
<xs:element name="Author" type="String32"
minOccurs="1" maxOccurs="1" />
<xs:element name="Title" type="String32"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexContent>
</xs:complexType>
</xs:schema>
My attempted new XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://custombookshop.com"
targetNamespace="custombookshop.com">
<xs:redefine schemaLocation="http://bookshop.com">
<xs:complexType name="Book">
<xs:complexContent>
<xs:extension base="Book">
<xs:sequence>
<xs:element name="Publisher" type="String32"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>
Your original schema should declare the sequence
inside the complexType
:
<xs:complexType name="Book">
<xs:sequence>
<xs:element name="Author" type="String32"
minOccurs="1" maxOccurs="1" />
<xs:element name="Title" type="String32"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
It should also declare the targetNamespace
equal to the default xmlns
namespace, and include the attribute elementFormDefault="qualified"
so you can use unqualified elements in your instance. The schema below (to which I added an element
declaration and a simpleType
declaration) validates your original XML:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://bookshop.com"
targetNamespace="http://bookshop.com"
elementFormDefault="qualified">
<xs:complexType name="Book">
<xs:sequence>
<xs:element name="Author" type="String32"
minOccurs="1" maxOccurs="1" />
<xs:element name="Title" type="String32"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:element name="Book" type="Book"/>
<xs:simpleType name="String32">
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
</xs:schema>
Assuming that the schema above as your original schema, you can redefine the Book
complex type in a new schema with the same target namespace as your original schema. If it needs to contain a Publisher
element from another namespace, you have to declare it in a third schema. In a schema with the same target namespace as your original schema, you can redefine the Book
type like this (assuming your original schema is in bookshop.xsd
:
<xs:redefine schemaLocation="bookshop.xsd">
<xs:complexType name="Book">
<xs:complexContent>
<xs:extension base="Book">
<xs:sequence>
<xs:element ref="cs:Publisher" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
For that to work you have to import the schema where the Publisher
element is declared. Suppose it is declared in this schema, with the http://custombookshop.com
namespace:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns="http://custombookshop.com"
xmlns:bs="http://bookshop.com"
targetNamespace="http://custombookshop.com">
<xs:import namespace="http://bookshop.com" schemaLocation="bookshop.xsd"/>
<xs:element name="Publisher" type="bs:String32" />
</xs:schema>
You can then import it into your redefined schema:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns="http://bookshop.com"
targetNamespace="http://bookshop.com"
xmlns:cs="http://custombookshop.com">
<xs:import schemaLocation="custombookshop.xsd" namespace="http://custombookshop.com"/>
<xs:redefine schemaLocation="bookshop.xsd">
...
</xs:redefine>
</xs:schema>
And now, you can validate your second XML file using the redefined schema.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With