如何使用Schematron评估SOAP响应?

时间:2018-01-18 03:32:59

标签: soap 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元素没有名为&#39; foo&#39;

的属性
<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)
    }
}

}

1 个答案:

答案 0 :(得分:0)

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元素。如果模式适用于该更改,则您已将问题缩小到名称空间问题。)