如何根据其用途定义具有空 $value 的元素?

How to define an element with empty $value dependent on its use?

在 XSD 1.1 中工作 我有一个包含文本元素的模式,我应该在其中用标签“关键字”标记某些单词。像这样:

例如 1: <text>I have a <keyword>specific</keyword> taste.</text>

这些关键字既可以是可见的,也可以是定义为关键字元素中的可选属性的类别的一部分。关键字应该指的是这样一个类别,或者将搜索到的关键字作为字符串包含在其中,或者显示两者的组合。所以它们应该像这样自由混合:

例 2: <text>The <keyword group='weapon'>sword</keyword> that I used is <keyword group='smithing'/>made of <keyword>steel</keyword>.</text>

到目前为止一切顺利。但现在我应该构建一个条件结构,它也使用这些关键字,但不在文本本身中显示它们。因此,当仅引用类别但关键字元素内没有字符串时,要求仅像第二个示例中那样引用它们。这是强制性的,因为元素内的所有字符串稍后都应该由另一个程序读取。目标是这样的:

例如 3: <text><condition><keyword group='sword'/><keyword group='handle'/></condition>By now swinging it, the sheer fore is cutting through my <keyword>enemies</keyword>.</text>

相比之下,类似这样的事情应该被禁止,因为条件关键字元素中的字符串将显示在以后应该可读的字符串中:

例如 4: <text><condition><keyword group='weapon'>sword</keyword><keyword group='handle'/></condition>By now swinging it, the sheer fore is cutting through my <keyword>enemies</keyword>.</text>

我现在的任务是禁止这样的结构。我如何意识到这一点?在我的模式中,我假设我需要构建一个断言作为条件元素的一部分,但我不知道如何去做。我已经尝试过几种这样的方法:

例如 5:

<xs:complexType name="condition" mixed="true">
    <xs:sequence>
        <xs:element name="keyword" type="keyword" minOccurs="1" maxOccurs="5"/>        
    </xs:sequence>
    <xs:assert test="string-length($value) = 0"/>
</xs:complexType>

例如 6:

<xs:complexType name="condition" mixed="true">
    <xs:sequence>
        <xs:element name="keyword" type="keyword" minOccurs="1" maxOccurs="5"/>        
    </xs:sequence>
    <xs:assert test="$value eq ''"/>
</xs:complexType>

例如 7:

<xs:complexType name="condition" mixed="true">
    <xs:sequence>
        <xs:element name="keyword" type="keyword" minOccurs="1" maxOccurs="5"/>        
    </xs:sequence>
    <xs:assert test="::child::string-length() = 0"/>
</xs:complexType>

当我有一个错误的 XML 代码时(如示例 4)或者甚至抛出断言评估失败的错误消息,他们都没有发现这种情况。我究竟做错了什么?我该如何解决这个问题?

如果您知道 XPath 2,那就很容易了:

<xs:complexType name="condition" mixed="true">
    <xs:sequence>
        <xs:element name="keyword" type="keyword" minOccurs="1" maxOccurs="5"/>        
    </xs:sequence>
    <xs:assert test="every $keyword in keyword satisfies string-length($keyword) eq 0"/>
</xs:complexType>

我认为这也可以在没有断言的情况下完成(或 XSD 1.1):condition 的复杂类型中 keyword 的局部元素声明可以具有与keyword 的全局定义和局部定义可以有一个空的内容模型。