XSD Validation of a Web API 2 response with multiple namespaces

I’m having a problem, and I’m not sure if it is lack of understanding on my part, something that Web API 2 cannot do. I’m not really versed in XSD validation (yet).

I’m building a Web API project used by clients to get information on people. To make communication with consumers of the API easier, the XML response of the API must validate according to a set of XSD-documents (One main XSD that imports other XSD’s for the complex properties on the Person object).

I believe the problem lies in the multiple namespaces that are defined in the main XSD for the complex properties, that I cannot get the Web API to create in its response. Specifically the error in validation is: The element 'person' in namespace 'http://url.com/person' has invalid child element 'address' in namespace 'http://url.com/person'. List of possible elements expected: 'element1' in namespace 'http://url.com/object' as well as 'address' in namespace 'http://url.com/address'.

It basically says the node Address is invalid in namespace1, but finds it in namespace2.

Concrete example: The database holds people, and every person has an address as a complex property. The XSD looks something like this:

  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  xmlns:address="http://url.com/address" targetNamespace="http:///url.com/person" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:import namespace="http://url.com/address" schemaLocation="Adresses API 0.2.xsd"/>
<xs:complexType name="Person">
        <xs:complexContent>
            <xs:extension base="party:Individual">
                <xs:sequence>
                    <xs:element name="name" type="xs:string" nillable="true" minOccurs="0"/>
                    <xs:element name="birthdate" type="xs:date" nillable="true" minOccurs="0"/>         
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

I snipped a lot of what I think is not applicable, of course, so it probably is not valid now, but it illustrates the idea. You see that this XSD imports another XSD for Address, which is below (Again, stripped and changed any info that’s too much or I cannot show )

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:address="http://url.com/address" targetNamespace="http://url.com/address" elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:import namespace="http://url.com/bag" schemaLocation="Bag API 0.2.xsd"/>
<xs:complexType name="InternationalAddress">
        <xs:sequence>
            <xs:element name="adresline1" type="xs:string" nillable="true" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>Stuff</xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="adresline2" type="xs:string" nillable="true" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>More stuff</xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="region" type="xs:string" nillable="true" minOccurs="0"/>
            <xs:element name="country" type="xs:string" nillable="true" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

I build an XML validator in my Web Api that does the following, xsdLocation points to the XSD file and xml is the xml in the response of my web API

XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("http://url.com/person", xsdLocation);

XDocument document = XDocument.Load(new StringReader(xml));

bool errors = false;
document.Validate(schemas, (o, e) =>
{
     Debug.WriteLine(e.Message);
     errors = true;
});
Debug.WriteLine("Response {0}", errors ? "did not validate" : "is valid");

And finally here is the XML that Web API spits out that needs to be validated, again, snipped and modified to only the important parts.

<person xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://url.com/person">
<address xmlns:d2p1="http://url.com/address" i:type="d2p1:InternationalAddress">      
  <d2p1:addressline1 i:nil="true" /> 
  <d2p1:addressline1 i:nil="true" /> 
  <d2p1:region i:nil="true" /> 
  <d2p1:country i:nil="true" /> 
</address>
<name>Test</name>
           ... SNIP...
 </person>

This all seems to work only for the validation of the simple attributes of the main person object. However, on the complex properties like Address (that are validated by another XSD that gets imported) it gives the error message mentioned above.

I suppose my XML needs another namespace at the top, and needs to namespace that Address node, but I cannot get Web Api to spit out XML that validates, no matter how many [XMLRoot], [XMLElement] or whatever attributes I throw at it. I tried several options found all over StackOverflow of different atrtibutes, IsReference=true named parameters on DataContract attributes, almost everything short of writing my own XML serializer.

Can anybody help me get in the right direction to validating my XML to this set of XSD’s?

I can do almost anything I want with the Web Api project to mould the XML, but the XSD’s are delivered by an external architect and those cannot change.

Thanks!


Source: xml

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.