Schematron验证元素值的计数

时间:2016-05-19 06:21:22

标签: xml xslt xpath schematron

假设我有一个XML文档定义:

NSString *str = @"12: a15xx";
str = [str stringByReplacingOccurrencesOfString:@"[^0-9]"
                                     withString:@""
                                        options:NSRegularExpressionSearch
                                          range:NSMakeRange(0, str.length)];

NSLog(@"%d", str.integerValue); // prints 1215

我想在每个<上下文中验证 ELEMENT> ,其每个Equipement / EqID最多由4个位置/传感器/ EqID引用。在这个例子中没有问题,因为EqID'2'被引用了3次而EqId'1'只被引用了一次。

每个<元素>是独立对待的。

我对schematron和xsl不太熟悉所以我甚至不确定它是否可以完成!

由于

编辑: 感谢martin解决方案usint XSLT 2.0,但在我的上下文中,我被迫使用XSLT 1.0。

EDIT2:我发布了一个XSTL 1.0解决方案

2 个答案:

答案 0 :(得分:1)

这是一个使用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>

您将收到第二个No more than 4 references元素的错误消息ELEMENT

答案 1 :(得分:0)

这是使用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])  &lt;= $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]) &lt;= $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>

任何改进/建议/评论都将不胜感激 马克