【问题标题】:Schematron applied to different xsi namespacesSchematron 应用于不同的 xsi 命名空间
【发布时间】:2015-09-17 10:07:16
【问题描述】:

我们有一个带有 xsi 命名空间的 schematron,声明如下

   <schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding='xslt2'>
   <ns prefix="xsi" uri="http://www.w3.org/2001/XMLSchema-instance"/>

我们这样做是因为我们想定义基于上下文的规则如下:

    <rule context="*[@xsi:type='DATA_TYPE']">...</rule>

这些规则适用于我们迄今为止收到的过去的 XML 文件。但是,我们最近收到了一个 XML,其 xsi 命名空间定义为:

xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" 

这个“新”xsi 命名空间导致上面定义的规则不被触发(因为规则不共享相同的 xsi)。有没有办法以独立于 xsi 命名空间触发规则的方式定义 schematron 命名空间?

总是可以选择基于 local-name()="type" 而不是使用 xsi:type 来定义规则,但我想知道是否有正确(和更好)的方法来实现这一点。

【问题讨论】:

  • (略略):XSI namespace is reserved。这个“新的”xsi 命名空间根本不是 XSI 命名空间,从验证的角度来看,它只是另一个命名空间。此外,您应该不需要使用您的架构检查此有效性,引用:“这加强了这些属性的特殊状态,因此它们不仅不需要在实例中声明为允许,但不得声明。它还消除了对 xsi:type 或 xsi:nil 等进行实验 [..] 的任何诱惑,因为它们没有任何效果,因此会产生严重的误导。”
  • 可能不是那么离题,因为它可以解决问题:)

标签: xml xslt xml-namespaces schematron


【解决方案1】:

这是旧规范中 XMLSchema-instance 命名空间的一个版本。

您可以为其添加另一个前缀声明:

<ns prefix="xsi_old" uri="http://www.w3.org/2000/10/XMLSchema-instance"/>

然后调整你的规则来测试两者:

<rule context="*[@xsi:type='DATA_TYPE' or @xsi_old:type='DATA_TYPE']">...</rule>

【讨论】:

  • 但要做到这一点,您需要提前了解世界上存在的所有命名空间。我认为可能还有更旧的版本。
  • 然后完全忽略命名空间,正如您使用local-name() 提到的,或者更广泛地说,测试namespace-uri() 以查看它是否包含XMLSchema-instance
  • 另一种方法是让文档所有者更新他们的 XML(或者在您的正常 Schematron 处理之前有一个自动更新它的阶段)。毕竟,“新”命名空间被采用已经 15 年了。
  • 同意你的看法,可能最好的想法是通知所有者,或者在收到时将xsi命名空间更新为正确的命名空间。我会将您的答案标记为有效,因为您提供了几种解决此问题的方法,但修复源可能是更好的选择。
猜你喜欢
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 2014-12-31
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 2021-07-02
  • 1970-01-01
相关资源
最近更新 更多