使用Schematron

时间:2018-04-06 10:40:50

标签: xml xpath schematron

我想使用Schematron比较两个XML文件。我有一个模板,如下所示:

  <action name="thirdAction" id="3">      
<return-values>
  <return-value name="communication-profile-id" />
  <return-value name="messaging-profile-id" />
</return-values>

当一个人创建一个动作实例时,它看起来像这样:

  <instanceOfAction name="thirdAction" id="3">     
    <results>
     <result name="communication-profile-id" />
     <result name="messaging-profile-id" />
    </results>
 </instanceOfAction>

我想基于id将instanceOfAction映射到给定的动作,然后检查子元素是否&#39;名字对应。在我的层次结构中,我有很多行动,这使得这更加困难。有人建议实施吗?我成功检查了instanceOfAction中的结果是否在SOME定义的操作中,但在具有相同id的操作中没有具体,通过执行以下操作:

   <sch:rule context="//ts:instanceOfAction/ts:results/ts:result">  
      <sch:assert test="$testspecification//(ts:actions/ts:action/ts:return-values/ts:return-value)[@name= current()/@key]">
        The keys from the results do not match with the names from the return-values.
      </sch:assert>
    </sch:rule>

其中变量$ testspecification是根层次结构的路径,其中包含所有XML文件。

任何帮助或想法将不胜感激。 :)

1 个答案:

答案 0 :(得分:1)

您可以使用xPath谓词查找匹配的action,就像您找到匹配的return-value一样。您可以使用..上升一个级别(或使用ancestor::轴)。

<sch:rule context="//ts:instanceOfAction/ts:results/ts:result">  
  <sch:assert test="$testspecification//ts:actions/ts:action[@id= current()/../../@id]/ts:return-values/ts:return-value[@name= current()/@key]">
    The keys from the results do not match with the names from the return-values.
  </sch:assert>
</sch:rule>

如上所述,规则的弱点在于它不会捕获results缺少模板指定的result的情况。如果我正在编写规则,我可以通过将上下文设置为ts:instanceOfAction来接近它,然后使用断言来验证instanceOfAction是否包含Action指定的所有内容,如下所示:

<sch:rule context="ts:instanceOfAction">  
  <sch:assert test="every $returnValue in $testspecification//ts:actions/ts:action[@id= current()/@id]/ts:return-values/ts:return-value satisfies $returnValue/@name = current()/ts:results/ts:result/@name and
                    every $result in ts:results/ts:result satisfies $result/@name = $testspecification//ts:actions/ts:action[@id= current()/@id]/ts:return-values/ts:return-value/@name">
    The keys from the results should match with the names from the return-values.
  </sch:assert>
</sch:rule>

(我还没有测试过上面的样本,因此可能需要进行一些修改。)

从问题标题来看,听起来您可能也有兴趣断言result元素与模板相比处于正确的序列中。您可以使用XPath position()函数来帮助检查。