将ISO XSL转换为SVRL XSL的解决方案咨询
Got it, let's break down exactly how to convert your ISO-formatted Schematron XSL into SVRL-compliant XSL based on the examples you shared. The core goal is to replace simple xsl:message error outputs with proper SVRL elements that Schematron validation tools expect, while preserving all your original validation logic.
Key Conversion Steps
Here are the critical changes you'll need to apply to each template and assertion:
Add a
<svrl:fired-rule>at the start of your template
This tells Schematron tools that the rule for the matched context has been triggered. Include thecontextattribute matching your template'smatchvalue, and the SVRL namespace.Replace
<xsl:message>with<svrl:failed-assert>
For each assertion failure case (thexsl:otherwiseblock), swap out thexsl:messagewith asvrl:failed-assertelement. Add atestattribute set to the same expression used in the correspondingxsl:whentest.Include the
locationattribute for failed assertions
Use theschematron-select-full-pathmode to generate a precise path to the invalid node, which simplifies debugging. This is done via anxsl:attributethat applies templates to the current node in that mode.Wrap error text in
<svrl:text>
Move your error message text fromxsl:textintosvrl:textinside thefailed-assertelement.Expand
xsl:apply-templatesto include all node types
Update theselectattribute to cover comments and processing instructions (along with attributes and elements) to ensure full traversal of the XML document.Ensure consistent mode names
Make sure themodevalue in your template andxsl:apply-templatesmatches (e.g., switch fromM23toM20as in your SVRL example, or keep it consistent if using a custom mode name).
Converted Example (From Your ISO XSL)
Here's how your original ISO template translates to SVRL-compliant XSL, following all the above steps:
<xsl:template match="sh:StandardBusinessDocument" priority="1000" mode="M20"> <svrl:fired-rule context="sh:StandardBusinessDocument" xmlns:svrl="http://purl.oclc.org/dsdl/svrl"/> <!-- ASSERT: sh:StandardBusinessDocumentHeader is required --> <xsl:choose> <xsl:when test="sh:StandardBusinessDocumentHeader"/> <xsl:otherwise> <svrl:failed-assert test="sh:StandardBusinessDocumentHeader" xmlns:svrl="http://purl.oclc.org/dsdl/svrl"> <xsl:attribute name="location"> <xsl:apply-templates mode="schematron-select-full-path" select="."/> </xsl:attribute> <svrl:text>sh:StandardBusinessDocumentHeader is required.</svrl:text> </svrl:failed-assert> </xsl:otherwise> </xsl:choose> <!-- ASSERT: ef:Package is required --> <xsl:choose> <xsl:when test="ef:Package"/> <xsl:otherwise> <svrl:failed-assert test="ef:Package" xmlns:svrl="http://purl.oclc.org/dsdl/svrl"> <xsl:attribute name="location"> <xsl:apply-templates mode="schematron-select-full-path" select="."/> </xsl:attribute> <svrl:text>ef:Package is required.</svrl:text> </svrl:failed-assert> </xsl:otherwise> </xsl:choose> <!-- ASSERT: xsi:schemaLocation must contain PackageProxy_1_2.xsd --> <xsl:choose> <xsl:when test="contains(@xsi:schemaLocation,'PackageProxy_1_2.xsd')"/> <xsl:otherwise> <svrl:failed-assert test="contains(@xsi:schemaLocation,'PackageProxy_1_2.xsd')" xmlns:svrl="http://purl.oclc.org/dsdl/svrl"> <xsl:attribute name="location"> <xsl:apply-templates mode="schematron-select-full-path" select="."/> </xsl:attribute> <svrl:text>sh:StandardBusinessDocument xsi:schemaLocation must be 'PackageProxy_1_2.xsd'</svrl:text> </svrl:failed-assert> </xsl:otherwise> </xsl:choose> <!-- ASSERT: Invoice element with non-empty xsi namespace --> <xsl:choose> <xsl:when test="not(name()= 'Invoice') or string-length(normalize-space(string(namespace::xsi))) != 0"/> <xsl:otherwise> <svrl:failed-assert test="not(name()= 'Invoice') or string-length(normalize-space(string(namespace::xsi))) != 0" xmlns:svrl="http://purl.oclc.org/dsdl/svrl"> <xsl:attribute name="location"> <xsl:apply-templates mode="schematron-select-full-path" select="."/> </xsl:attribute> <svrl:text>Invoice element and xmlns:xsi attribute with no null values.</svrl:text> </svrl:failed-assert> </xsl:otherwise> </xsl:choose> <xsl:apply-templates mode="M20" select="@*|*|comment()|processing-instruction()"/> </xsl:template>
Additional Notes
- To avoid repeating the SVRL namespace declaration on every element, declare it once at the root of your XSLT document (e.g., on the
xsl:stylesheetelement):<xsl:stylesheet xmlns:svrl="http://purl.oclc.org/dsdl/svrl" ...> - Ensure the
schematron-select-full-pathmode template exists in your XSLT—this is a standard Schematron helper template that generates the XPath path to a node. If you don't have it, you'll need to include it (it’s typically part of standard Schematron XSLT libraries).
内容的提问来源于stack exchange,提问作者Tester3

