如何使用 Schematron 验证所有 'signedWhen' xml 属性不应包含时区信息?我正在使用使用 XPath 1.0 的 .NET 实现。
给定源 XML:
<?xml version="1.0" encoding="utf-8"?>
<MyData versionDate="2010-12-09" dataBeginDate="2012-03-01" dataEndDate="2012-03-10" extractedWhen="2012-03-09T10:08:40">
<Site Site_key="999">
<SitePatient Patient_key="1">
<txt_Surname value="TEST" signedWhen="2012-03-08T22:02:39" signedWho="SomeName"/>
<txt_GivenNames value="PATIENT" signedWhen="2012-03-08T22:02:39" signedWho="SomeName"/>
<dat_BirthDate value="2010-06-15" signedWhen="2012-03-08T22:02:39" signedWho="SomeName"/>
<sel_Status value="Enrolled" signedWhen="2012-03-08T22:02:39" signedWho="SomeName"/>
<dat_StatusDate value="2012-03-05-05:00" signedWhen="2012-03-08T22:02:39" signedWho="SomeName"/>
</SitePatient>
</Site>
</MyData>
在 XSD 文件中使用此 Schematron 规则:
<xs:annotation>
<xs:appinfo>
<sch:pattern name="All signedWhen TimeZone constraints">
<sch:rule context="*[@signedWhen]">
<sch:assert test="(substring(@signedWhen,11,12) != '-') and (substring(@signedWhen,11,12) != '+') and (substring(@signedWhen,11,12) != 'Z')">
<name/> must not include TimeZone information
</sch:assert>
</sch:rule>
</sch:pattern>
</xs:appinfo>
</xs:annotation>
给出这些不正确的结果
它不应该返回任何结果,因为没有时区信息。
NMatrix.Schematron.ValidationException: Results from Schematron validation:
Results from Schematron validation
From pattern "All signedWhen TimeZone constraints"
Assert fails: txt_Surname must not include TimeZone information
At: /MyData[1]/Site[1]/SitePatient[1]/txt_Surname[1]
<txt_Surname value="TEST" signedWhen="2012-03-08T22:02:39" signedWho="SomeName">...</txt_Surname>
(Line: 5, Column: 6)
Assert fails: txt_GivenNames must not include TimeZone information
At: /MyData[1]/Site[1]/SitePatient[1]/txt_GivenNames[1]
<txt_GivenNames value="PATIENT" signedWhen="2012-03-08T22:02:39" signedWho="SomeName">...</txt_GivenNames>
(Line: 6, Column: 6)
Assert fails: dat_BirthDate must not include TimeZone information
At: /MyData[1]/Site[1]/SitePatient[1]/dat_BirthDate[1]
<dat_BirthDate value="2010-06-15" signedWhen="2012-03-08T22:02:39" signedWho="SomeName">...</dat_BirthDate>
(Line: 7, Column: 6)
Assert fails: sel_Status must not include TimeZone information
At: /MyData[1]/Site[1]/SitePatient[1]/sel_Status[1]
<sel_Status value="Enrolled" signedWhen="2012-03-08T22:02:39" signedWho="SomeName">...</sel_Status>
(Line: 8, Column: 6)
Assert fails: dat_StatusDate must not include TimeZone information
At: /MyData[1]/Site[1]/SitePatient[1]/dat_StatusDate[1]
<dat_StatusDate value="2012-03-05-05:00" signedWhen="2012-03-08T22:02:39" signedWho="SomeName">...</dat_StatusDate>
(Line: 9, Column: 6)
编辑1:
我想到了。我在测试中没有正确使用 XPath 1.0 函数“子字符串”。
<sch:assert test="(substring(@signedWhen, 11, 1) != '-') and (substring(@signedWhen, 11, 1) != '+') and (substring(@signedWhen, 11, 1) != 'Z')">
编辑 2: W3schools 对 xs:date 和 xs:dateTime 的定义没有提到可选负签名年份的可能性。所以我上面的代码不起作用,请参阅下面选择的答案。
编辑 3: 好吧,我使用的模式 (xmlns:xs="http://www.w3.org/2001/XMLSchema" ) 不接受负符号年份 - 并声明它无效。但为了安全起见,我将从现在开始使用此代码:
<sch:assert test="not ( (contains(substring(@signedWhen, 11, 2), '-')) or (contains(@signedWhen, '+')) or (contains(@signedWhen, 'Z')) )">