Schematron 文件中的自定义命名空间“localFunction”导致转换崩溃

问题描述 投票:0回答:1

我有一个 Schematron 文件 (.sch),其中包含像“localFunctions”这样的命名空间。它用于调用同一文件中的本地函数。但是当我尝试进行验证时,使用 schxslt (10.1.0) 编译 Schematron 文件,然后使用 SaxonCS (12.5.0) 转换 xml 和 Schematron,并导致出现“SXST0001”错误代码。当我深入到错误位置并注释掉函数调用行时,一切都很完美。我尝试提供像“http://example.com/fct”这样的名称空间,但没有任何改变。

这是 Schematron 文件的命名空间

<schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fct="localFunctions" queryBinding="xslt2">
    <ns prefix="gl-plt" uri="http://www.xbrl.org/int/gl/plt/2010-04-16"/>
    <ns prefix="gl-cor" uri="http://www.xbrl.org/int/gl/cor/2006-10-25"/>
    <ns prefix="gl-bus" uri="http://www.xbrl.org/int/gl/bus/2006-10-25"/>
    <ns prefix="gl-muc" uri="http://www.xbrl.org/int/gl/muc/2006-10-25"/>
    <ns prefix="xbrli" uri="http://www.xbrl.org/2003/instance"/>
    <ns prefix="ds" uri="http://www.w3.org/2000/09/xmldsig#"/>
    <ns prefix="xades" uri="http://uri.etsi.org/01903/v1.3.2#"/>
    <ns prefix="edefter" uri="http://www.edefter.gov.tr"/>
    <ns prefix="fct" uri="localFunctions"/>
    <ns prefix="defterek" uri="http://www.edefter.gov.tr/ek"/>
    <title>Büyük defter dokümanlarını kontrol etmek için gerekli olan schematron kuralları</title>
    <let name="periodCoveredStart" value="/edefter:defter/xbrli:xbrl/gl-cor:accountingEntries/gl-cor:documentInfo/gl-cor:periodCoveredStart"/>
    <let name="periodCoveredEnd" value="/edefter:defter/xbrli:xbrl/gl-cor:accountingEntries/gl-cor:documentInfo/gl-cor:periodCoveredEnd"/>
    <let name="vknTckn" value="/edefter:defter/xbrli:xbrl/xbrli:context/xbrli:entity/xbrli:identifier"/>
    <let name="donemYil" value="substring($periodCoveredStart,1,4)"/>
    <let name="donemAy" value="substring($periodCoveredStart,6,2)"/>
    <let name="donem" value="number(concat($donemYil,$donemAy))"/>
    <let name="dosyaAdi" value="base-uri()"/>

这是导致问题的规则

<pattern id="accountingentries">
        <rule context="/edefter:defter/xbrli:xbrl/gl-cor:accountingEntries">
            <assert test="gl-cor:documentInfo">gl-cor:documentInfo zorunlu bir elemandır.</assert>
            <assert test="gl-cor:entityInformation">gl-cor:entityInformation zorunlu bir elemandır.</assert>
            <let name="accoundMainIdList" value="gl-cor:entryHeader/gl-cor:entryDetail[1]/gl-cor:account/normalize-space(gl-cor:accountMainID)"/>
            ---Commenting this line fixes everything. But this function is also part of the validation. ---><assert test="fct:isSorted($accoundMainIdList)">Büyük defterde hesaplar, ana hesap numarası bazında sıralı olmalıdır.</assert>
            <let name="altHesabiOlmayanAnaHesapListesi" value="gl-cor:entryHeader/gl-cor:entryDetail[1]/gl-cor:account[count(gl-cor:accountSub)=0]/normalize-space(gl-cor:accountMainID)"/>
            <let name="altHesabiOlmayanAnaHesapSayisi" value="count($altHesabiOlmayanAnaHesapListesi)"/>
            <let name="farkliAltHesabiOlmayanAnaHesapSayisi" value="count(distinct-values($altHesabiOlmayanAnaHesapListesi))"/>
            <assert test="$altHesabiOlmayanAnaHesapSayisi = $farkliAltHesabiOlmayanAnaHesapSayisi">Alt hesabı olmayan aynı hesaplar aynı gl-cor:entryHeader elemanı içerisinde bulunmalıdır.</assert>
            <let name="altHesapListesi" value="gl-cor:entryHeader/gl-cor:entryDetail[1]/gl-cor:account/gl-cor:accountSub/normalize-space(gl-cor:accountSubID)"/>
            <let name="altHesapSayisi" value="count($altHesapListesi)"/>
            <let name="farkliAltHesapSayisi" value="count(distinct-values($altHesapListesi))"/>
            <assert test="$altHesapSayisi = $farkliAltHesapSayisi">Aynı alt hesaplar aynı gl-cor:entryHeader elemanı içerisinde bulunmalıdır.</assert>
        </rule>
    </pattern>

这是函数定义

<xsl:function name="fct:isSorted" as="xs:boolean">
        <xsl:param name="accoundMainIdList" as="xs:string*"/>
        <xsl:variable name="sortedAccountMainIdList" as="xs:string*">
            <xsl:for-each select="$accoundMainIdList">
                <xsl:sort/>
                <xsl:value-of select="."/>
            </xsl:for-each>
        </xsl:variable>
        <xsl:variable name="s1">
            <xsl:value-of select="string-join($accoundMainIdList,'|')"/>
        </xsl:variable>
        <xsl:variable name="s2">
            <xsl:value-of select="string-join($sortedAccountMainIdList,'|')"/>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="$s1 = $s2">
                <xsl:value-of select="true()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="false()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
xml xslt saxon schematron
1个回答
0
投票

2016 年 Schematron ISO 规范中的规则表示“在 XSLT2 命名空间中,模式元素之前可以使用 XSLT2 函数元素。”。

我认为 Schxslt 确实实现了这一点,而其他 Schematron 实现可能或过去更加宽松,因此针对这些实现进行测试的 Schematron 作者可能会发布一个无法按 Schxslt 预期工作的模式。

© www.soinside.com 2019 - 2024. All rights reserved.