Search code examples
phpsoapdomdocumentxsd-validation

Envelope': No matching global declaration available for the validation root error when validating SOAP response in php


Im trying to validate an soap response envelope but keep getting errors

i have this soap response which I can not alter (response.xml)

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
    <GetVehicleMakesResponse xmlns="http://api.examle.com/">
        <GetVehicleMakesResult>
            <VehicleMakes xmlns="">
                <VehicleMake>
                    <MakeID>37</MakeID>
                    <MakeName>ALFA ROMEO</MakeName>
                </VehicleMake>
                <VehicleMake>
                    <MakeID>3</MakeID>
                    <MakeName>AUDI</MakeName>
                </VehicleMake>
                <VehicleMake>
                    <MakeID>19</MakeID>
                    <MakeName>BMW</MakeName>
                </VehicleMake>
            </VehicleMakes>
        </GetVehicleMakesResult>
    </GetVehicleMakesResponse>
</soap:Body>

and I have an XSD file to validate this against (GetVehicleMakes.xsd)

<xs:schema xmlns:tns="http://api.examle.com/" attributeFormDefault="unqualified" elementFormDefault="qualified" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
  <xs:element name="GetVehicleMakesResponse">
        <xs:complexType>
              <xs:sequence>
                    <xs:element name="GetVehicleMakesResult">
                          <xs:complexType>
                                <xs:sequence>
                                      <xs:element name="VehicleMakes">
                                            <xs:complexType>
                                                  <xs:sequence>
                                                        <xs:element maxOccurs="unbounded" name="VehicleMake">
                                                              <xs:complexType>
                                                                    <xs:sequence>
                                                                          <xs:element name="MakeID" type="xs:unsignedByte" />
                                                                          <xs:element name="MakeName" type="xs:string" />
                                                                    </xs:sequence>
                                                              </xs:complexType>
                                                        </xs:element>
                                                  </xs:sequence>
                                            </xs:complexType>
                                      </xs:element>
                                </xs:sequence>
                          </xs:complexType>
                    </xs:element>
              </xs:sequence>
        </xs:complexType>
  </xs:element>

when I validate this the response against the XSD using PHP DOM Document

$xml = new DOMDocument(); 
$xml->load('response.xml');
$xml->schemaValidate('GetVehicleMakes.xsd')

I get the following Error

Error 1845: Element '{http://www.w3.org/2003/05/soap-envelope}Envelope': No matching global declaration available for the validation root. in file:/P:/xampp/htdocs/test/response.xml on line 1

Can anyone shed some insights in how I can solve this error please?


Solution

  • This is a declaration issue. In the xml response the namespace for the soap envelope element differs from the namespace defined in the xsd file.

    In the xsd file is the following defined:

    <xs:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
    

    But the soap envelope element in the response is defined with the namespace http://www.w3.org/2003/05/soap-envelope. As your error message sais, the validation against the xsd does not know this specific namespace for the envelope element.

    As you cannot alter the soap response, you have to edit the xsd file. Just import the correct envelope definition.

    <xs:import namespace="http://www.w3.org/2003/05/soap-envelope" schemaLocation="http://www.w3.org/2003/05/soap-envelope"/>
    

    You might recognize, that the validation lasts for a few seconds. This is quite normal because of excessive traffic on definitions the w3c released. The w3c has set delays on definition requests. To avoid these delays, you can save the definitions to a local file and use them instead.