2015-03-24 3 views
1

Я использую Schematron для проверки некоторых бизнес-правил. Мой данные XML выглядит следующим образом:Schematron - проверка элемента на основании его позиции

<labtests> 
    <test> 
     <observation> 
      <code code="TT900" name="NMCK"/> 
      <outcome value="074042"/> 
     </observation>    
    </test> 

    <test> 
     <observation> 
      <code code="TT500" name="LVCT"/> 
      <outcome value="852417"/> 
     </observation>    
    </test> 
    <test> 
     <observation> 
      <code code="TT500" name="LVCT"/> 
      <outcome value="36542"/> 
     </observation>    
    </test> 
    <test> 
     <observation> 
      <code code="TT100" name="GVMC"/> 
      <outcome value="874541"/> 
     </observation>    
    </test> 
    <test> 
     <observation> 
      <code code="TT500" name="LVCT"/> 
      <outcome value="369521"/> 
     </observation>    
    </test> 
</labtests> 

Текущий контекст установлен labtests/test/observation, как показано ниже:

<iso:rule context="labtests/test/observation"> 
    <!--perform all validations here--> 


</iso:rule>    

Я хочу, чтобы выполнить некоторые специальные проверки проверки бизнеса на <outcome> узла для первых <observation> блока, имеющего code/@code="TT500" ,

Я думаю, что я могу использовать следующее выражение, чтобы получить позицию первого намеченные <observation> блок

count(../../test/observation/code[@code="TT500"]/preceding-sibling::*)+1 

, но я не знаю, как сравнить эту позицию с узлом в текущем контексте для выполнения специальной проверки ,

UPDATE:

Для простоты предположим, что специальная проверка будет проводиться в данном случае является то, что длина outcome/@value должна быть больше или равна 6. т.е.

<iso:report test="not(string-length(outcome/@value) >= 6"> 
    outcome/@value should have at least 6 characters for the first TT500 observation 
</iso:report> 
+0

объяснить, что ваш должно выполняться утверждение или правило, с какими узлами он связан, и в какой ситуации он должен утверждать или сообщать (то есть, что разрешено, а что нет). Еще лучше: покажите ** два ** документа, один из которых действителен, а второй - нет. –

+0

@ MathiasMüller См. Обновленный вопрос. –

ответ

2

Следующий документ Schematron выполняет именно то, что вы просили. Нет никакой реальной разницы между assert и report, вы можете инвертировать любое правило, чтобы соответствовать обоим.

<?xml version="1.0" encoding="UTF-8"?> 
<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2"> 
    <pattern> 
     <rule context="observation[code/@code = 'TT500' and not(preceding::observation[code/@code = 'TT500'])]"> 
      <assert test="string-length(outcome/@value) ge 6"> outcome/@value should have at least 6 characters for the first TT500 observation </assert> 
     </rule> 
    </pattern> 
</schema> 

Когда следующее (недействительный) XML документ проверяется с этим правилом SCH:

процессор
<?xml version="1.0" encoding="UTF-8"?> 
<?xml-model href="sample.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> 
<labtests> 
    <test> 
     <observation> 
      <code code="TT900" name="NMCK"/> 
      <outcome value="07442"/> 
     </observation>    
    </test> 
    <test> 
     <observation> 
      <code code="TT500" name="LVCT"/> 
      <outcome value="85417"/> 
     </observation>    
    </test> 
    <test> 
     <observation> 
      <code code="TT500" name="LVCT"/> 
      <outcome value="36542"/> 
     </observation>    
    </test>   
</labtests> 

Schematron будет выдавать предупреждение вдоль линий

E [ISO Schematron] outcome/@value should have at least 6 characters for the first TT500 observation 
+0

Работает как шарм. Никогда не знал, что фильтры могут быть применены в узле ''. Дурак я. –

+2

@AJQarshi Добро пожаловать. Значение внутри 'sch: rule' может фактически быть любым [XSLT-образцом] (http://www.w3.org/TR/xslt20/#dt-pattern), который является всего лишь подмножеством всех возможных выражений. –

Смежные вопросы