Schematron 检查给定类属性值的位置

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

我想创建一个 Schematron 模式来验证:

  • 如果
    /html/body/main/div/div
    处的元素具有可选的
    class
    属性,则在任何情况下它都包含
    cat1
    cat2
    值之一。
  • 如果 /html/body/main/div/div 处的元素
    not
    具有可选的
    class
    属性,则在任何情况下它都 not 包含值
    cat1
    cat2
    之一。

这是一个有效的例子:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head></head>
    <body>
        <main>
            <div class="name">
                <div class="cat1 cat3"> <!— Other values are acceptable as long as cat1 or cat2 is present. —>
                    <div></div>
                </div>
                <div class="cat2">
                    <div></div>
                </div>
                <div> <!— No class attribute is OK —>
                    <div></div>
                </div>
            </div>
        </main>
    </body>
</html>

还有一个无效的例子:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head></head>
    <body>
        <main>
            <div class="name cat1"> <!— cat1 not allowed here —>
                <div class="cat3"> <!— cat1 or cat2 missing —>
                    <div></div>
                </div>
                <div class="cat2">
                    <div class="cat2"></div> <!— cat2 not allowed here —>
                </div>
                <div class=""> <!— Empty class attribute is not OK —>
                </div>
            </div>
        </main>
    </body>
</html>

这是我到目前为止所得到的。 XPath 查询

//*[not(self::html/body/main/div/div)]
不起作用。它还返回位于
/html/body/main/div/div
的节点。

<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
    <pattern id="test">
        <rule context="//*[not(self::html/body/main/div/div)]">
            <assert test="
                    not(contains(@class, ’cat1’)) and
                    not(contains(@class, ’cat2’))
                    " role="error"> 
                        The class cannot contain 
                        "<value-of select="@class"/>". 
            </assert>
        </rule>
    </pattern>
</schema>
xml schema schematron
1个回答
0
投票

我会尝试

<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3">
    <ns prefix="xhtml" uri="http://www.w3.org/1999/xhtml"/>
    <let name="cats" value="('cat1', 'cat2')"/>
    <let name="divs" value="/xhtml:html/xhtml:body/xhtml:main/xhtml:div/xhtml:div"/>
    <pattern>
        <rule context="*[not(. intersect $divs)]/@class">
          <assert test="every $cat in $cats satisfies not(contains-token(., $cat))">@class '<value-of select="."/>' contains one of $cats values '<value-of select="$cats"/>'</assert>
        </rule>
        <rule context="$divs">
            <assert test="@class = $cats">@class value '<value-of select="@class"/>' not equal to $cats '<value-of select="$cats"/>'</assert>
        </rule>
    </pattern>
</schema>

我假设 xslt3 绑定,因为现在 Schematron 通常使用当前版本的 Saxon 进行编译,并且这些支持 XSLT 3。

其中大部分也应该像 xslt2 一样工作,不确定 contains-token。

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