我有这样的文件结构:
bookmap.ditamap
├── en-US/
│ └── CTR_MyProduct.ditamap
├── es-ES/
│ └── CTR_MyProduct.ditamap
└── fr-FR/
└── CTR_MyProduct.ditamap
bookmap.ditamap的内容是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd">
<bookmap>
<booktitle><mainbooktitle/></booktitle>
<part>
<mapref href="en-US/CTR_Product.ditamap"/>
</part>
<part>
<mapref href="fr-FR/CTR_Product.ditamap"/>
</part>
</bookmap>
我想要一个Schematron规则,它应该在子目录中爬行,寻找以CTR_
开头、以.ditamap
结尾的文件,如果没有相应的<part>
元素,就会抱怨,比如:
<part>
<mapref href="xx-YY/CTR_Product.ditamap"/>
</part>
在本例中,西班牙语(es-ES
(映射没有<part>
元素。这应该报告。您认为这是否可以在Schematron中进行验证?
有了底层XSLT/XXPath3支持和Saxon 9或10或11,您可能可以执行例如
every $uri in uri-collection('?select=CTR_Product.ditamap;recurse=yes')
satisfies
some $part in part
satisfies contains($uri, $part/mapref/@href)
如果这些元素在一个名称空间中,您还需要将其设置为默认的XPath选择名称空间。
您也可以使用通配符,例如uri-collection('?select=CTR_*.ditamap;recurse=yes')
。
也许使用ends-with($uri, $part/mapref/@href)
而不是contains($uri, $part/mapref/@href)
是更好的检查方式。
在Schematron:的背景下更完整
<sch:rule context="bookmap">
<sch:let name="parts" value="part"/>
<sch:let name="uris" value="uri-collection('?select=*.ditamap;recurse=yes')"/>
<sch:assert test="every $uri in $uris
satisfies
some $part in part
satisfies ends-with($uri, $part/mapref/@href)">
Not every URI exists.
<sch:value-of select="$uris[not(some $ref in $parts/mapref satisfies ends-with(., $ref/@href))]"/>
</sch:assert>
</sch:rule>