【问题标题】:Compare if order of elements matches in 2 XML files with Schematron比较 2 个 XML 文件中的元素顺序是否与 Schematron 匹配
【发布时间】:2018-04-06 10:40:49
【问题描述】:

我想使用 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 映射到给定的操作,然后检查子元素的名称是否对应。在我的层次结构中,我有很多动作使这变得更加困难。有人有实施此的建议吗?通过执行以下操作,我成功检查了 instanceOfAction 中的结果是否在某些定义的操作中,但不是专门在具有相同 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 文件。

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

【问题讨论】:

    标签: xml xpath schematron


    【解决方案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() 函数来帮助检查。

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 2010-11-09
      相关资源
      最近更新 更多