0

I have a SOAP response below

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
    <ns2:getCountryResponse xmlns:ns2="http://spring.io/guides/gs-producing-web-service">
        <ns2:country>
            <ns2:name>Spain</ns2:name>
            <ns2:population>46704314</ns2:population>
            <ns2:capital>Madrid</ns2:capital>
            <ns2:currency>EUR</ns2:currency>
        </ns2:country>
    </ns2:getCountryResponse>
</SOAP-ENV:Body>

and a Schematron file which I expect to spit out an error when I run the validation since the Header element does not have an attribute named 'foo'

<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
<sch:ns uri="http://www.w3.org/2003/05/soap-envelope" prefix="SOAP-ENV"/>
<sch:pattern id="structure">
    <sch:rule context="SOAP-ENV:Header">
        <sch:assert test="@foo">The element Header must have an attribute named foo.</sch:assert>
    </sch:rule>
</sch:pattern>

But I get no failures. What am I getting wrong? The code that I use for validation is

internal class SchematronValidatorUtil {
companion object {
    @JvmStatic
    fun isXmlStringValidAgainstSchema(schema: String, xml: String,
                                      charset: Charset = StandardCharsets.UTF_8): SchematronResult {

        val schematronResource = SchematronResourcePure.fromString(schema, charset)
        val input = StreamSource(ByteArrayInputStream(xml.toByteArray(charset)))

        val schematronOutput = schematronResource.applySchematronValidationToSVRL(input)
        val failures = mutableListOf<String>()
        return schematronOutput?.let { schemaOutput ->
            schemaOutput.activePatternAndFiredRuleAndFailedAssert
                    .map { each -> each as? FailedAssert }
                    .forEach { each -> each?.let { value ->
                        failures.add(String.format("%s: %s", value.test, value.text)) } }

            val type = if (failures.any())
                SchematronResultType.XmlDoesNotMatchSchema else SchematronResultType.XmlMatchesSchema
            return SchematronResult(type, failures)
        } ?: SchematronResult(SchematronResultType.InvalidSchematronFile, failures)
    }
}

}

Satyam
  • 645
  • 2
  • 7
  • 20

1 Answers1

0

The SOAP envelope declares the SOAP-ENV namespace prefix as http://schemas.xmlsoap.org/soap/envelope/

The Schematron schema declares the SOAP-ENV namespace prefix as http://www.w3.org/2003/05/soap-envelope

Change the ns declaration in the Schematron schema to match the namespace URI declared in the SOAP envelope, and it should work.

(A useful way to test an issue like this is to temporarily change the rule context to *:Header, which would match the Header element in any namespace. If the schema works with that change, then you've narrowed the problem down to a namespace issue.)

Joshua Legler
  • 236
  • 1
  • 5
  • That is what fixed it. Thank you! And thanks for the tip. I tried something similar without intending to. I tested it using the context as "/" which executed the rule. Now I know why. – Satyam Jan 21 '18 at 11:56