2012-03-13 56 views
1

如何使用Schematron驗證所有'signedWhen'xml屬性都不應該有時區信息?我正在使用使用XPath 1.0的.NET實現。如何使用Schematron驗證xml屬性不應該有時區信息?

由於源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函數「substring」。

<sch:assert test="(substring(@signedWhen, 11, 1) != '-') and (substring(@signedWhen, 11, 1) != '+') and (substring(@signedWhen, 11, 1) != 'Z')"> 

編輯2:日期和xs: XS的W3Schools的日期時間確定指標並未提及可選負簽訂一年的可能性。所以我上面的代碼不起作用,請看下面選擇的答案。

編輯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')))"> 

回答

1

我不知道,如果你想處理日期或日期時間,但是當我看到你的代碼,也許兩者兼而有之。您的代碼在某些特定情況下不起作用。

鑑於dateTime specification

該·詞法空間·日期時間組成的形式的字符 有限長度的序列的:「 - 」? yyyy' - 'mm' - 'dd'T'hh':'mm':'ss ('。's +)? (zzzzzz)?,其中...

您可以閱讀更多細節。所述(zzz)?部分是時區和是如下(同一來源):

一個時區的詞彙表示是以下形式的字符串: ((「+」 |「 - 」)HH「:」毫米)| 「Z」,其中...

所以,你的代碼將不會爲日期或日期時間一樣工作:-2010-03-08Z2010-03-08T12:01:02.2Z,例如。

這一個應該更通用(和XPath 1。0):

test="not(
      contains(@signedWhen,'+') 
      or contains(@signedWhen,'Z') 
      or (contains(@signedWhen, 'T') 
       and contains(substring-after(@signedWhen ,':'),'-')) 
      or (not(contains(@signedWhen,'T')) and contains(@signedWhen,':')) 
      )" 
+0

我的代碼應該適用於你的一個例子「2010-03-08T ..」,但你是對的,它將不適用於「-2010-03-08Z」我沒有意識到是可能的,但我現在只是在這裏檢查xs:Date,但將它擴展到xs:dateTime是有道理的,就像將來一樣。謝謝! – user610064 2012-03-16 11:58:32

+0

我基於xs:date的日期爲「http://www.w3schools.com/schema/schema_dtypes_date.asp」,它表示'+'和' - '必須在日期之後,並且與'T'相同,所以如果這是真的我的代碼將100%正確的xs:date - AFAIK。還在xs:dateTime的頁面看下去,我的代碼也會100%兼容......? – user610064 2012-03-16 12:14:16

+0

對於'dateTime',時區位於最後,所以它不在字符串表示的第11位。關於第一個「 - 」,它只涉及BC日期而不是時區。我認爲你提到的w3school頁面忘記了關於第一個「 - 」(BC日期)的這一點。對於任何疑問,我寧願看一看w3c rec(上面的dateTime鏈接)。 – 2012-03-16 15:16:53