Schematron 验证元素值的计数
Schematron validating count of element value
假设我有一个 XML 文档定义:
<Root>
<ELEMENT>
<Equipement>
<EqID>1</EqID>
</Equipement>
<Equipement>
<EqID>2</EqID>
</Equipement>
<Location>
<Sensor>
<EqID>2</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
<Location>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
</ELEMENT>
<ELEMENT>
...
</ELEMENT>
</Root>
我想验证 在每个 的上下文中,每个 Equipement/EqID 最多被 4 个 Location/Sensor/EqID 引用。在这个例子中是可以的,因为 EqID '2' 被引用了 3 次而 EqId '1' 只被引用了一次。
每个 都是独立对待的。
我对 schematron 和 xsl 不是很熟悉,所以我什至不确定它是否可以完成!
谢谢
编辑:
感谢马丁使用 XSLT 2.0 的解决方案,但在我的上下文中,我被迫使用 XSLT 1.0。
EDIT2:我在下面发布了 XSTL 1.0 解决方案
这是一个使用 XPath 2.0 表达式的 Schematron 示例:
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:title>Occurence</sch:title>
<sch:let name="max-count" value="4"/>
<sch:pattern id="occurence-test">
<sch:rule context="/Root/ELEMENT">
<sch:assert test="every $eid in Equipement/EqID satisfies count(Location/Sensor/EqID[. = $eid]) le $max-count">No more than <sch:value-of select="$max-count"/> references</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
示例文件
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="test2016051801.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<Root>
<ELEMENT>
<Equipement>
<EqID>1</EqID>
</Equipement>
<Equipement>
<EqID>2</EqID>
</Equipement>
<Location>
<Sensor>
<EqID>2</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
<Location>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
</ELEMENT>
<ELEMENT>
<Equipement>
<EqID>1</EqID>
</Equipement>
<Location>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
</Location>
</ELEMENT>
</Root>
您将收到第二个 ELEMENT
元素的错误消息 No more than 4 references
。
这是一个使用 xslt 1.0 的解决方案
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
<sch:title>Occurence</sch:title>
<sch:let name="max-count" value="4"/>
<sch:pattern id="occurence-test">
<sch:rule context="/Root/ELEMENT/Equipement">
<sch:let name="eqid" value="EqID"/>
<sch:assert test="count(parent::*/Location/Sensor[EqID = $eqid]) <= $max-count">EqID <sch:value-of select="$eqid"/> is referenced <sch:value-of select="count(parent::*/Location/Sensor[EqID = $eqid])"/> times. No more than <sch:value-of select="$max-count"/> references</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
使用 Martin 的示例文件,它会产生预期的输出
<svrl:failed-assert test="count(parent::*/Location/Sensor[EqID = $eqid]) <= $max-count" location="/Root/ELEMENT[2]/Equipement">
<svrl:text>EqID 1 is referenced 5 times. No more than 4 references</svrl:text>
</svrl:failed-assert>
任何 improvement/suggestion/comment 将不胜感激
马克
假设我有一个 XML 文档定义:
<Root>
<ELEMENT>
<Equipement>
<EqID>1</EqID>
</Equipement>
<Equipement>
<EqID>2</EqID>
</Equipement>
<Location>
<Sensor>
<EqID>2</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
<Location>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
</ELEMENT>
<ELEMENT>
...
</ELEMENT>
</Root>
我想验证 在每个
每个
我对 schematron 和 xsl 不是很熟悉,所以我什至不确定它是否可以完成!
谢谢
编辑: 感谢马丁使用 XSLT 2.0 的解决方案,但在我的上下文中,我被迫使用 XSLT 1.0。
EDIT2:我在下面发布了 XSTL 1.0 解决方案
这是一个使用 XPath 2.0 表达式的 Schematron 示例:
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:title>Occurence</sch:title>
<sch:let name="max-count" value="4"/>
<sch:pattern id="occurence-test">
<sch:rule context="/Root/ELEMENT">
<sch:assert test="every $eid in Equipement/EqID satisfies count(Location/Sensor/EqID[. = $eid]) le $max-count">No more than <sch:value-of select="$max-count"/> references</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
示例文件
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="test2016051801.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<Root>
<ELEMENT>
<Equipement>
<EqID>1</EqID>
</Equipement>
<Equipement>
<EqID>2</EqID>
</Equipement>
<Location>
<Sensor>
<EqID>2</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
<Location>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>2</EqID>
</Sensor>
</Location>
</ELEMENT>
<ELEMENT>
<Equipement>
<EqID>1</EqID>
</Equipement>
<Location>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
<Sensor>
<EqID>1</EqID>
</Sensor>
</Location>
</ELEMENT>
</Root>
您将收到第二个 ELEMENT
元素的错误消息 No more than 4 references
。
这是一个使用 xslt 1.0 的解决方案
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
<sch:title>Occurence</sch:title>
<sch:let name="max-count" value="4"/>
<sch:pattern id="occurence-test">
<sch:rule context="/Root/ELEMENT/Equipement">
<sch:let name="eqid" value="EqID"/>
<sch:assert test="count(parent::*/Location/Sensor[EqID = $eqid]) <= $max-count">EqID <sch:value-of select="$eqid"/> is referenced <sch:value-of select="count(parent::*/Location/Sensor[EqID = $eqid])"/> times. No more than <sch:value-of select="$max-count"/> references</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
使用 Martin 的示例文件,它会产生预期的输出
<svrl:failed-assert test="count(parent::*/Location/Sensor[EqID = $eqid]) <= $max-count" location="/Root/ELEMENT[2]/Equipement">
<svrl:text>EqID 1 is referenced 5 times. No more than 4 references</svrl:text>
</svrl:failed-assert>
任何 improvement/suggestion/comment 将不胜感激 马克