【发布时间】:2018-03-08 20:30:34
【问题描述】:
我正在运行核心 schematron XSLT(从 http://schematron.com/front-page/the-schematron-skeleton-implementation/ 下载)针对我的带有 include 语句的 schematron 规则。尝试通过中间 XSL 运行要测试的 XML 实例时,对于包含的 schematron 中存在的每个规则,它都会失败,并显示“不明确的规则匹配”。
"描述:不明确的规则匹配 /filing:FilingMessage/filing:FilingConnectedDocument[1]/ecf:DocumentAugmentation[1]/ecf:DocumentRendition[1]/nc:Attachment[1]/nc:BinaryFormatText[1] 两者都匹配 “{http://release.niem.gov/niem/niem-core/3.0/}BinaryFormatText”在文件的第 192 行:/C:/_working/misc/schematron/schematron/trunk/schematron/code/temp.xsl 和 “{http://release.niem.gov/niem/niem-core/3.0/}BinaryFormatText”在文件的第 175 行:/C:/_working/misc/schematron/schematron/trunk/schematron/code/temp.xsl 网址:http://www.w3.org/TR/xslt20/#err-XTRE0540"。
在检查生成的中间 XSL 时,包含在包含的 schematron 文件中的规则似乎被两次呈现到中间 XSL 中。检查 XSL 文件iso_schematron_skeleton_for_saxon.xsl,看起来iso:include 使用模式节点和规则节点调用规则模板,导致数据重复。
我会假设 github 上的 schematron XSLT 是 schematron 规范的最终实现。不是这样吗?或者任何人都可以对此发表评论,因为我认为我必须调整 schematron XSLT 以使其工作是正确的?
基本 Schematron
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<title>Test Schematron Illustrating Transform Bug</title>
<ns prefix="x" uri="http://www.w3.org/TR/REC-html40"/>
<ns prefix="filing" uri="https://docs.oasis-open.org/legalxml-courtfiling/ns/v5.0/filing"/>
<ns prefix="nc" uri="http://release.niem.gov/niem/niem-core/3.0/"/>
<include href="ExternalTestPattern.sch"/>
<pattern id="ecf">
<rule context="/filing:FilingMessage">
<assert test="./nc:DocumentIdentification/nc:IdentificationID">DocumentID must be present.</assert>
</rule>
</pattern>
</schema>
ExternalTestPattern.sch Schematron
<?xml version="1.0" encoding="UTF-8"?>
<pattern xmlns="http://purl.oclc.org/dsdl/schematron" id="code-list-rules">
<!-- Required namespace declarations as indicated in this set of rules:
<ns prefix="nc" uri="http://release.niem.gov/niem/niem-core/3.0/"/> -->
<rule context="nc:BinaryFormatText">
<assert test="( false() or ( contains('application/jsonapplication/mswordapplication/pdfapplication/vnd.oasis.opendocument.textapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/xml',concat('',.,'')) ) ) ">Invalid binary format code value.</assert>
</rule>
</pattern>
我忘记提及的另一件事是,如果我只是使用像 Oxygen 或 XML buddy 这样的 XML 编辑器来使用我的 schematron 来验证 XML 实例,它就可以正常工作。
当我使用 Oxygen 加载我的 Test.sch 和 iso_schematron_message_xslt2.xslt 时,生成的 XSLT 如下所示。中途您会看到 ExternalTestPattern.sch (match="nc:BinaryFormatText") 中定义的规则模板是重复的:
<xsl:stylesheet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:schold="http://www.ascc.net/xml/schematron" xmlns:iso="http://purl.oclc.org/dsdl/schematron" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:x="http://www.w3.org/TR/REC-html40" xmlns:filing="https://docs.oasis-open.org/legalxml-courtfiling/ns/v5.0/filing" xmlns:nc="http://release.niem.gov/niem/niem-core/3.0/" version="2.0">
<!--Implementers: please note that overriding process-prolog or process-root is the preferred method for meta-stylesheets to use where possible. -->
<xsl:param name="archiveDirParameter"/>
<xsl:param name="archiveNameParameter"/>
<xsl:param name="fileNameParameter"/>
<xsl:param name="fileDirParameter"/>
<xsl:variable name="document-uri">
<xsl:value-of select="document-uri(/)"/>
</xsl:variable>
<!--PHASES-->
<!--PROLOG-->
<xsl:output method="text"/>
<!--XSD TYPES FOR XSLT2-->
<!--KEYS AND FUNCTIONS-->
<!--DEFAULT RULES-->
<!--MODE: SCHEMATRON-SELECT-FULL-PATH-->
<!--This mode can be used to generate an ugly though full XPath for locators-->
<xsl:template match="*" mode="schematron-select-full-path">
<xsl:apply-templates select="." mode="schematron-get-full-path"/>
</xsl:template>
<!--MODE: SCHEMATRON-FULL-PATH-->
<!--This mode can be used to generate an ugly though full XPath for locators-->
<xsl:template match="*" mode="schematron-get-full-path">
<xsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
<xsl:text>/</xsl:text>
<xsl:choose>
<xsl:when test="namespace-uri()=''">
<xsl:value-of select="name()"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>*:</xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:text>[namespace-uri()='</xsl:text>
<xsl:value-of select="namespace-uri()"/>
<xsl:text>']</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="preceding" select="count(preceding-sibling::*[local-name()=local-name(current()) and namespace-uri() = namespace-uri(current())])"/>
<xsl:text>[</xsl:text>
<xsl:value-of select="1+ $preceding"/>
<xsl:text>]</xsl:text>
</xsl:template>
<xsl:template match="@*" mode="schematron-get-full-path">
<xsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
<xsl:text>/</xsl:text>
<xsl:choose>
<xsl:when test="namespace-uri()=''">@<xsl:value-of select="name()"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>@*[local-name()='</xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:text>' and namespace-uri()='</xsl:text>
<xsl:value-of select="namespace-uri()"/>
<xsl:text>']</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--MODE: SCHEMATRON-FULL-PATH-2-->
<!--This mode can be used to generate prefixed XPath for humans-->
<xsl:template match="node() | @*" mode="schematron-get-full-path-2">
<xsl:for-each select="ancestor-or-self::*">
<xsl:text>/</xsl:text>
<xsl:value-of select="name(.)"/>
<xsl:if test="preceding-sibling::*[name(.)=name(current())]">
<xsl:text>[</xsl:text>
<xsl:value-of select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
<xsl:text>]</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="not(self::*)">
<xsl:text/>/@<xsl:value-of select="name(.)"/>
</xsl:if>
</xsl:template>
<!--MODE: SCHEMATRON-FULL-PATH-3-->
<!--This mode can be used to generate prefixed XPath for humans
(Top-level element has index)-->
<xsl:template match="node() | @*" mode="schematron-get-full-path-3">
<xsl:for-each select="ancestor-or-self::*">
<xsl:text>/</xsl:text>
<xsl:value-of select="name(.)"/>
<xsl:if test="parent::*">
<xsl:text>[</xsl:text>
<xsl:value-of select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
<xsl:text>]</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="not(self::*)">
<xsl:text/>/@<xsl:value-of select="name(.)"/>
</xsl:if>
</xsl:template>
<!--MODE: GENERATE-ID-FROM-PATH -->
<xsl:template match="/" mode="generate-id-from-path"/>
<xsl:template match="text()" mode="generate-id-from-path">
<xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
<xsl:value-of select="concat('.text-', 1+count(preceding-sibling::text()), '-')"/>
</xsl:template>
<xsl:template match="comment()" mode="generate-id-from-path">
<xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
<xsl:value-of select="concat('.comment-', 1+count(preceding-sibling::comment()), '-')"/>
</xsl:template>
<xsl:template match="processing-instruction()" mode="generate-id-from-path">
<xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
<xsl:value-of select="concat('.processing-instruction-', 1+count(preceding-sibling::processing-instruction()), '-')"/>
</xsl:template>
<xsl:template match="@*" mode="generate-id-from-path">
<xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
<xsl:value-of select="concat('.@', name())"/>
</xsl:template>
<xsl:template match="*" mode="generate-id-from-path" priority="-0.5">
<xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
<xsl:text>.</xsl:text>
<xsl:value-of select="concat('.',name(),'-',1+count(preceding-sibling::*[name()=name(current())]),'-')"/>
</xsl:template>
<!--MODE: GENERATE-ID-2 -->
<xsl:template match="/" mode="generate-id-2">U</xsl:template>
<xsl:template match="*" mode="generate-id-2" priority="2">
<xsl:text>U</xsl:text>
<xsl:number level="multiple" count="*"/>
</xsl:template>
<xsl:template match="node()" mode="generate-id-2">
<xsl:text>U.</xsl:text>
<xsl:number level="multiple" count="*"/>
<xsl:text>n</xsl:text>
<xsl:number count="node()"/>
</xsl:template>
<xsl:template match="@*" mode="generate-id-2">
<xsl:text>U.</xsl:text>
<xsl:number level="multiple" count="*"/>
<xsl:text>_</xsl:text>
<xsl:value-of select="string-length(local-name(.))"/>
<xsl:text>_</xsl:text>
<xsl:value-of select="translate(name(),':','.')"/>
</xsl:template>
<!--Strip characters--><xsl:template match="text()" priority="-1"/>
<!--SCHEMA SETUP-->
<xsl:template match="/">
<xsl:apply-templates select="/" mode="M0"/>
<xsl:apply-templates select="/" mode="M5"/>
</xsl:template>
<!--SCHEMATRON PATTERNS-->
<!--PATTERN code-list-rules-->
<!--RULE -->
<xsl:template match="nc:BinaryFormatText" priority="1000" mode="M0">
<!--ASSERT -->
<xsl:choose>
<xsl:when test="( false() or ( contains('application/jsonapplication/mswordapplication/pdfapplication/vnd.oasis.opendocument.textapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/xml',concat('',.,'')) ) ) "/>
<xsl:otherwise>
<xsl:message>Invalid binary format code value. (( false() or ( contains('application/jsonapplication/mswordapplication/pdfapplication/vnd.oasis.opendocument.textapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/xml',concat('',.,'')) ) ))</xsl:message>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="*|comment()|processing-instruction()" mode="M0"/>
</xsl:template>
<xsl:template match="text()" priority="-1" mode="M0"/>
<xsl:template match="@*|node()" priority="-2" mode="M0">
<xsl:apply-templates select="*|comment()|processing-instruction()" mode="M0"/>
</xsl:template>
<!--RULE -->
<xsl:template match="nc:BinaryFormatText" priority="1000" mode="M0">
<!--ASSERT -->
<xsl:choose>
<xsl:when test="( false() or ( contains('application/jsonapplication/mswordapplication/pdfapplication/vnd.oasis.opendocument.textapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/xml',concat('',.,'')) ) ) "/>
<xsl:otherwise>
<xsl:message>Invalid binary format code value. (( false() or ( contains('application/jsonapplication/mswordapplication/pdfapplication/vnd.oasis.opendocument.textapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/xml',concat('',.,'')) ) ))</xsl:message>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="*|comment()|processing-instruction()" mode="M0"/>
</xsl:template>
<!--PATTERN ecf-->
<!--RULE -->
<xsl:template match="/filing:FilingMessage" priority="1000" mode="M5">
<!--ASSERT -->
<xsl:choose>
<xsl:when test="./nc:DocumentIdentification/nc:IdentificationID"/>
<xsl:otherwise>
<xsl:message>DocumentID must be present. (./nc:DocumentIdentification/nc:IdentificationID)</xsl:message>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="*|comment()|processing-instruction()" mode="M5"/>
</xsl:template>
<xsl:template match="text()" priority="-1" mode="M5"/>
<xsl:template match="@*|node()" priority="-2" mode="M5">
<xsl:apply-templates select="*|comment()|processing-instruction()" mode="M5"/>
</xsl:template>
</xsl:stylesheet>
任何启蒙都会非常有帮助。 谢谢
【问题讨论】:
-
我无法重现。它在 oXygen 中验证,没有警告,我手动编译了 XSLT,没有看到在相同模式下匹配的重复模板。您可以发布生成的 XSLT 吗?链接到您认为可疑的 iso_schematron_skeleton_for_saxon.xsl 中的行? github.com/Schematron/schematron/blob/master/trunk/schematron/…
-
谢谢麦兹。似乎导致问题的行是第 1260 行“
" 在模板 第 1218 行内。选择是 2 个节点的结果集(在这种情况下),这会导致规则模板运行两次。跨度> -
您是否正在使用
iso_schematron_message_xslt2.xslt转换您的Schematron 文件?应该应用一系列转换,在将 Schematron 编译成 XSLT 时,输出将用作下一个 XSLT 的输入。
标签: xslt schematron