XSD 唯一元素和属性 [英] XSD unique elements and attributes

查看:36
本文介绍了XSD 唯一元素和属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家!这是我关于 stackoverflow 的第一个问题,尽管我经常阅读本网站上的帖子.

everybody! This is my first question on stackoverflow, although I'm regularly reading posts on this site.

为了切入正题,我试图定义一个如下所示的 XML 模式:

To get to the point, I'm trying to define an XML Schema that looks as following:

<xs:element name="keyConfiguration">
<xs:complexType>
  <xs:sequence>
    <xs:element name="move">
      <xs:complexType>
        <xs:attribute name="N" type="keyCode"/>
        <xs:attribute name="NE" type="keyCode"/>
        <xs:attribute name="E" type="keyCode"/>
        <xs:attribute name="SE" type="keyCode"/>
        <xs:attribute name="S" type="keyCode"/>
        <xs:attribute name="SW" type="keyCode"/>
        <xs:attribute name="W" type="keyCode"/>
        <xs:attribute name="NW" type="keyCode"/>
      </xs:complexType>
    </xs:element>
    <xs:element name="wait" type="keyCode"/>
    <xs:element name="select" type="keyCode"/>
  </xs:sequence>
</xs:complexType>
<xs:unique name="uniqueKeyCode">
  <xs:selector xpath="."/>
  <xs:field xpath="move/@*"/>
  <xs:field xpath="wait"/>
  <xs:field xpath="select"/>
</xs:unique>

keyCode 是一种枚举类型,用于识别键盘按键,它接受 xs:int 的子集.

The keyCode is an enumeration type used to identify keyboard presses and it accepts a subset of xs:int.

这个想法是我不想验证将多个可能的操作映射到同一个键的 XML 文件,因此以下 XML 应该是无效的:

The idea is that I don't want to validate XML files that map multiple possible actions to the same key, so the following XML should be invalid:

<keyConfiguration>
  <move N="101" NE="101" E="102" SE="99" S="98" SW="97" W="100" NW="103"/>
  <wait>101</wait>
  <select>101</select>
</keyConfiguration>

移动到北、东北等的属性和等待/选择操作的元素都会重复,不应该发生.移动方向的所有属性和其他动作的所有元素都应该是唯一的.

Both attributes for moving to North, North-East etc. and elements for wait/select actions are repeated and none should happen. All atrributes for move directions and all elements for other actions should be unique.

遗憾的是,当我尝试根据 XSD 验证给定的 XML 时,它是有效的!我认为唯一标记中的 XPath 已损坏,但我不知道如何解决此问题(我尝试了多种变体,包括 <xs:field xpath="*/move/@*"/><xs:field xpath="*/wait"/> 并且它仍然没有工作).

Sadly, when I try to validate the given XML against the XSD, it is valid! I think the XPath's in the unique tag are broken, but I don't know how to fix this (I tried multiple variants, including <xs:field xpath="*/move/@*"/> and <xs:field xpath="*/wait"/> and it still didn't work).

提前致谢!

这里是完整的架构定义,如果有帮助的话:

here is the full schema definition, if it helps:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="keyCode">
    <xs:restriction base="xs:int">
      <xs:enumeration value="10"/> <!-- Enter -->
      ...
      <xs:enumeration value="96"/> <!-- NumPad-0 -->
      <xs:enumeration value="97"/> <!-- NumPad-1 -->
      <xs:enumeration value="98"/> <!-- NumPad-2 -->
      <xs:enumeration value="99"/> <!-- NumPad-3 -->
      <xs:enumeration value="100"/> <!-- NumPad-4 -->
      <xs:enumeration value="101"/> <!-- NumPad-5 -->
      <xs:enumeration value="102"/> <!-- NumPad-6 -->
      <xs:enumeration value="103"/> <!-- NumPad-7 -->
      <xs:enumeration value="104"/> <!-- NumPad-8 -->
      <xs:enumeration value="105"/> <!-- NumPad-9 -->
      ...
      </xs:restriction>
  </xs:simpleType>

  <xs:element name="keyConfiguration">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="move">
          <xs:complexType>
            <xs:attribute name="N" type="keyCode"/>
            <xs:attribute name="NE" type="keyCode"/>
            <xs:attribute name="E" type="keyCode"/>
            <xs:attribute name="SE" type="keyCode"/>
            <xs:attribute name="S" type="keyCode"/>
            <xs:attribute name="SW" type="keyCode"/>
            <xs:attribute name="W" type="keyCode"/>
            <xs:attribute name="NW" type="keyCode"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="wait" type="keyCode"/>
        <xs:element name="select" type="keyCode"/>
      </xs:sequence>
    </xs:complexType>
    <xs:unique name="uniqueKeyCode">
    <xs:selector xpath="."/>
      <xs:field xpath="*/move/@*"/>
      <xs:field xpath="*/wait"/>
      <xs:field xpath="*/select"/>
    </xs:unique>
  </xs:element>
</xs:schema>

也许跟命名空间有关系?我尝试在网上寻找 xpath 示例,但找不到任何可以帮助我确定问题的内容.谢谢!

Maybe it has something to do with the namespace? I tried looking on the web for with xpath examples, but I couldn't find anything that would help me identify the problem. Thanks!

推荐答案

我认为使用 XSD 1.0 无法做到这一点.Unique 以这种方式工作:xs:selector 选择一组元素,其中 fields 值应该是唯一的.

I don't think this can be done using XSD 1.0. Unique works this way: xs:selector selects a set of elements across wich the fields value should be unique.

因此,在选择器中,您应该选择每个 属性、 的值和 的值,并在字段中选择这些节点(点字符.").请记住,在 XPath 中,运算符 | 给出了节点集之间的联合.理想情况下,您可以使用它来解决您的问题:

So, in the selector you should select every attribute, the value of and the value of , and in the field the value of those nodes (dot character "."). Have in mind that in XPath the operator | gives the union between node-sets. Ideally you could use this to solve your problem:

<xs:unique name="uniqueKeyCode">
    <xs:selector xpath="move/@* | wait | select"/>
    <xs:field xpath="."/>
</xs:unique>

但是XSD 不允许在 xs:selector 中选择属性.但我希望你明白,如果 NNEW 等是元素而不是属性,你可以使用如下内容它会起作用:

However XSD does not allows to select attributes in xs:selector. But I hope you understand that if N, NE, W, etc were elemnts instead of attributes you are allowed to use something like the following and it will work:

<xs:unique name="uniqueKeyCode">
    <xs:selector xpath="move/* | wait | select"/>
    <xs:field xpath="."/>
</xs:unique>

这会起作用,因为您只是在 xs:selector 中选择元素.

And this will work because you are only selecting elements in xs:selector.

使用 XSD 1.1,这可以通过 xs:assert 来完成,它允许您使用 xpath(选择器、字段、唯一性等仅允许您使用受限的 XPath 子集).将解决此问题的示例断言:

Using XSD 1.1 this can be done using xs:assert, that allows you to use xpath (selector, field, unique, etc only allows you to use a restricted XPath subset). Example assertion that will solve this problem:

<xs:assert test="count(distinct-values(move/@* | wait | select)) = count(move/@* | wait | select)"/>

<小时>

另外请记住,使用范围(从 10 到 105)和使用联合(从 10 到 50 + 从 60 到 105)比使用 xs:enumeration 更容易定义 keyCode 类型.


In addition have in mind that is easier to define the keyCode type using ranges (from 10 to 105) and using unions (from 10 to 50 + from 60 to 105) rather than using xs:enumeration.

连续值示例:

<xs:simpleType name="keyCode">
    <xs:restriction base="xs:int">
        <xs:minInclusive value="10"/>
        <xs:maxInclusive value="105"/>
    </xs:restriction>
</xs:simpleType>

非连续值示例:

<xs:simpleType name="keyCode">
    <xs:union>
        <xs:simpleType>
            <xs:restriction base="xs:int">
                <xs:minInclusive value="10"/>
                <xs:maxInclusive value="50"/>
            </xs:restriction>
        </xs:simpleType>

        <xs:simpleType>
            <xs:restriction base="xs:int">
                <xs:minInclusive value="60"/>
                <xs:maxInclusive value="105"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:union>
</xs:simpleType>

这篇关于XSD 唯一元素和属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆