如何为XML片段编写此Schematron验证测试?

时间:2017-01-27 20:34:51

标签: xml xslt xpath xml-validation schematron

我有一个XML片段:

<AAA>
    <Field name="a"/>
    <Field name="b"/>
    <Field name="x"/>
    <User id="x" id2="f"/>
    <User id="y"/>
</AAA>
<AAA>
    <Field name="r"/>
    <Field name="z"/>
</AAA>

我需要规则,如果用户标记存在,则应检查 id id2 的属性值是否存在名称属性为字段。

因此,在第一个 AAA 标记中,它会验证并提供2个错误,因为 "f" 不存在作为字段名称, "y" 也不会。

AAA标记并不总是包含用户标记,而用户标记并不总是同时包含 id id2

我一直在搞乱一些XPath表达式,但无济于事。

1 个答案:

答案 0 :(得分:2)

如果您不能使用XPath 2.0,那么您可以编写以下Schematron规则:

ISO Schematron

<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">

    <sch:pattern>
        <sch:rule context="User[@id]">
            <sch:assert test="@id = ../Field/@name">User ID does not exist as a field!</sch:assert>
        </sch:rule>

        <sch:rule context="User[@id2]">
            <sch:assert test="@id2 = ../Field/@name">User ID2 does not exist as a field!</sch:assert>
        </sch:rule>
    </sch:pattern>

</sch:schema>

我假设一个没有命名空间的输入XML文档。如果User元素首先没有其中一个属性,或者AAA元素没有User元素,则断言不会失败。

你没有说清楚为什么Martin Honnen的建议不适合你,所以无论如何我都在这里列出。该规则看起来像:

<sch:pattern>
    <sch:rule context="AAA">
        <sch:report test="some $user in User satisfies not($user/(@id, @id2) = Field/@name)">User ID does not exist as a field!</sch:report>
    </sch:rule>
</sch:pattern>