schematron:我可以对命名空间进行分组吗

问题描述

我们的内容包含来自大约 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>

解决方法

在 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。

,

您可以使用以下结构:

*: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”。在里面。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...