我想创建一个 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>
我会尝试
<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。