用于查找无效记录的 SchemaTron 规则
SchemaTron rule to find invalid records
我正在尝试使用 Schematron 规则验证以下 XML。
XML:
<?xml version="1.0" encoding="utf-8"?>
<Biotic><Maul><Number>1</Number>
<Record><Code IDREF="a1"/>
<Detail><ItemID>1</ItemID></Detail>
<Detail><ItemID>3</ItemID></Detail>
</Record>
<Record><Code IDREF="b1"/>
<Detail><ItemID>3</ItemID></Detail>
<Detail><ItemID>4</ItemID></Detail>
</Record>
<Record><Code IDREF="b1"/>
<Detail><ItemID>4</ItemID></Detail>
<Detail><ItemID>6</ItemID></Detail>
</Record>
<Record><Code IDREF="c1"/>
<Detail><ItemID>5</ItemID></Detail>
<Detail><ItemID>5</ItemID></Detail>
</Record>
</Maul></Biotic>
并且检查是“ItemID 对于给定 Maul 中的给定代码应该是唯一的。”
因此根据要求,代码为 b1 的记录无效,因为 ItemId 4 存在于两条记录中。
同样,记录C1也是无效的,因为c1有两个itemId为5的节点。
记录a1有效,下一条记录中也有ItemID 3但编码不同
我试过的 Schematron 规则:
<?xml version="1.0" encoding="utf-8" ?><schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<title>Schematron validation rule</title>
<pattern id="P1">
<rule context="Maul/Record" id="R1">
<let name="a" value="//Detail/[./ItemID, ../Code/@IDREF]"/>
<let name="b" value="current()/Detail/[./ItemID, ../Code/@IDREF]"/>
<assert test="count($a[. = $b]) = count($b)">
ItemID should be unique for the given Code within the given Maul.
</assert>
</rule>
</pattern>
</schema>
这两个 let
值似乎有问题。他们将每个 return 一个 Detail
元素(及其所有内容,包括属性、子元素和文本节点)。我不确定谓词 [./ItemID, ../Code/@IDREF]
中的代码将要做什么,但我认为它将 return 具有子 ItemID
元素或子元素的所有 Detail
元素具有 @IDREF
属性的同级 Code
元素,无论 ItemID
或 @IDREF
的值是什么。
我想我会将规则/@context 更改为 ItemID,因此对于违反约束的每个 ItemID,断言都会失败一次。
这里有一个规则并断言它可以正常工作:
<?xml version="1.0" encoding="utf-8" ?><schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<title>Schematron validation rule</title>
<pattern id="P1">
<rule context="Maul/Record/Detail/ItemID" id="R1">
<assert test="count(ancestor::Maul/Record[Code/@IDREF = current()/ancestor::Record/Code/@IDREF]/Detail/ItemID[. = current()]) = 1">
ItemID should be unique for the given Code within the given Maul.
</assert>
</rule>
</pattern>
</schema>
assert 测试发现,在祖先 Maul
中,任何 Record
的 Code/@IDREF
等于 Record
的 Code/@IDREF
当前 ItemID
在。至少,它会找到一个 Record
(当前 ItemID
在的那个)。然后它会在那些 Record
中查找等于当前 ItemID
的任何 Detail/ItemID
。它会找到至少一个(当前 ItemID
)。 count
函数计算找到了多少 ItemID
。如果找到多个,则断言失败。
感谢 https://www.liquid-technologies.com/online-schematron-validator 的参考!我不知道那个工具。
我正在尝试使用 Schematron 规则验证以下 XML。
XML:
<?xml version="1.0" encoding="utf-8"?>
<Biotic><Maul><Number>1</Number>
<Record><Code IDREF="a1"/>
<Detail><ItemID>1</ItemID></Detail>
<Detail><ItemID>3</ItemID></Detail>
</Record>
<Record><Code IDREF="b1"/>
<Detail><ItemID>3</ItemID></Detail>
<Detail><ItemID>4</ItemID></Detail>
</Record>
<Record><Code IDREF="b1"/>
<Detail><ItemID>4</ItemID></Detail>
<Detail><ItemID>6</ItemID></Detail>
</Record>
<Record><Code IDREF="c1"/>
<Detail><ItemID>5</ItemID></Detail>
<Detail><ItemID>5</ItemID></Detail>
</Record>
</Maul></Biotic>
并且检查是“ItemID 对于给定 Maul 中的给定代码应该是唯一的。”
因此根据要求,代码为 b1 的记录无效,因为 ItemId 4 存在于两条记录中。
同样,记录C1也是无效的,因为c1有两个itemId为5的节点。
记录a1有效,下一条记录中也有ItemID 3但编码不同
我试过的 Schematron 规则:
<?xml version="1.0" encoding="utf-8" ?><schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<title>Schematron validation rule</title>
<pattern id="P1">
<rule context="Maul/Record" id="R1">
<let name="a" value="//Detail/[./ItemID, ../Code/@IDREF]"/>
<let name="b" value="current()/Detail/[./ItemID, ../Code/@IDREF]"/>
<assert test="count($a[. = $b]) = count($b)">
ItemID should be unique for the given Code within the given Maul.
</assert>
</rule>
</pattern>
</schema>
这两个 let
值似乎有问题。他们将每个 return 一个 Detail
元素(及其所有内容,包括属性、子元素和文本节点)。我不确定谓词 [./ItemID, ../Code/@IDREF]
中的代码将要做什么,但我认为它将 return 具有子 ItemID
元素或子元素的所有 Detail
元素具有 @IDREF
属性的同级 Code
元素,无论 ItemID
或 @IDREF
的值是什么。
我想我会将规则/@context 更改为 ItemID,因此对于违反约束的每个 ItemID,断言都会失败一次。
这里有一个规则并断言它可以正常工作:
<?xml version="1.0" encoding="utf-8" ?><schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<title>Schematron validation rule</title>
<pattern id="P1">
<rule context="Maul/Record/Detail/ItemID" id="R1">
<assert test="count(ancestor::Maul/Record[Code/@IDREF = current()/ancestor::Record/Code/@IDREF]/Detail/ItemID[. = current()]) = 1">
ItemID should be unique for the given Code within the given Maul.
</assert>
</rule>
</pattern>
</schema>
assert 测试发现,在祖先 Maul
中,任何 Record
的 Code/@IDREF
等于 Record
的 Code/@IDREF
当前 ItemID
在。至少,它会找到一个 Record
(当前 ItemID
在的那个)。然后它会在那些 Record
中查找等于当前 ItemID
的任何 Detail/ItemID
。它会找到至少一个(当前 ItemID
)。 count
函数计算找到了多少 ItemID
。如果找到多个,则断言失败。
感谢 https://www.liquid-technologies.com/online-schematron-validator 的参考!我不知道那个工具。