【问题标题】:schematron: can I group namespacesschematron:我可以对命名空间进行分组吗
【发布时间】:2021-07-16 09:37:17
【问题描述】:

我们的内容包含来自大约 8 个不同命名空间的内容。在下面的 schematron 规则中,我只是签入其中一个。我想按照规则检查其中 6 个元素而不是其他 2 个元素,我不确定执行此操作的最佳方法。我认为将 6 个命名空间分组并给它们一个前缀然后使用它会很好。可以这样做吗?

<pattern>
    <rule context="def:para | def:para-text | def:block | def:quote-para | def:source-para | def:note-para" role="warning">
        <report test="text()[contains(.,'www.')]">URLs should be marked up with a url tag</report>
    </rule>
</pattern>

【问题讨论】:

  • 感谢这两个答案都非常有帮助

标签: namespaces prefix schematron


【解决方案1】:

在 XML 中,您不能同时将多个命名空间 URI 映射到同一个前缀。命名空间的全部意义在于消除来自不同词汇表的同名元素(和属性)的歧义,因此它们没有提供将多个命名空间混为一谈的方法。

未经测试,但您可以匹配任何命名空间中的元素,然后仅测试不在不需要的命名空间中的元素:

<pattern>
    <rule context="*:para | *:para-text | *:block | *:quote-para |
                   *:source-para | *:note-para" role="warning">
        <report test=".[not(self::a:*) and not(self::b:*)]/text()[contains(.,'www.')]"
          >URLs should be marked up with a url tag</report>
    </rule>
</pattern>

从您的问题中不清楚同名元素是否可以出现在多个命名空间中。上面的代码假定在任何命名空间中都可以使用相同的本地名称,并且“a”和“b”前缀映射到您不想测试的命名空间的命名空间 URI。

【讨论】:

    【解决方案2】:

    您可以使用以下构造:

    *:ElementLocalName[namespace-uri()='http://namespace.tld']
    

    如果您使用 XSLT2,您可以像这样在架构顶部附近声明一个变量:

    <sch:let name="my6namespaces" value="('http://ns1.com', 'http://ns2.com', 'http://ns3.org', 'http://ns4.com, 'http://ns5.net', 'http://ns6.com')"/>
    

    然后你可以在你的规则中使用它:

    <pattern>
        <rule context="*:para[namespace-uri()=$my6namespaces] | *:para-text[namespace-uri()=$my6namespaces] | *:block[namespace-uri()=$my6namespaces] | *:quote-para[namespace-uri()=$my6namespaces] | *:source-para[namespace-uri()=$my6namespaces] | *:note-para[namespace-uri()=$my6namespaces]" role="warning">
            <report test="text()[contains(.,'www.')]">URLs should be marked up with a url tag</report>
        </rule>
    </pattern>
    

    如果它不会对性能造成太大影响,您可以像这样缩短规则上下文:

    <pattern>
        <rule context="*[local-name()=('para', 'para-text', 'block', 'quote-para', 'source-para', 'note-para') and namespace-uri()=$my6namespaces]" role="warning">
            <report test="text()[contains(.,'www.')]">URLs should be marked up with a url tag</report>
        </rule>
    </pattern>
    

    请注意,只要其中一个元素具有“www”,您当前编写的规则就会生成成功报告。在里面。我认为您可能打算将其写为assert 而不是report,在这种情况下,只要其中一个元素没有具有“www. "在里面。

    【讨论】:

    • 感谢 Joshua,这正是我的意思。我想我会经常使用这个。虽然在这个特殊的场合,我只是遵循了第一个建议,因为它今天会为我完成这项工作。报告类型正确,www 应始终在 url 中,而不是在 para 等中。
    • 现在我重新阅读了您的 ,感觉非常有道理!
    猜你喜欢
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 2016-03-02
    • 2012-06-24
    相关资源
    最近更新 更多