如何使用 Schematron 评估 SOAP 响应?

How to evaluate SOAP response using Schematron?

我在下面有一个 SOAP 响应

<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>

和一个 Schematron 文件,我希望在我 运行 验证时吐出一个错误,因为 Header 元素没有名为 '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>

但我没有失败。我错了什么?我用于验证的代码是

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)
    }
}

}

SOAP 信封将 SOAP-ENV 名称空间前缀声明为 http://schemas.xmlsoap.org/soap/envelope/

Schematron 模式将 SOAP-ENV 命名空间前缀声明为 http://www.w3.org/2003/05/soap-envelope

更改 Schematron 架构中的 ns 声明以匹配 SOAP 信封中声明的名称空间 URI,它应该可以工作。

(测试此类问题的一种有用方法是临时将规则上下文更改为 *:Header,这将匹配任何命名空间中的 Header 元素。如果架构适用于该更改,那么您已将问题缩小为命名空间问题。)