简体   繁体   English

XSD的独特元素和属性

[英]XSD unique elements and attributes

everybody! 大家好! This is my first question on stackoverflow, although I'm regularly reading posts on this site. 这是我关于stackoverflow的第一个问题,尽管我经常阅读此站点上的帖子。

To get to the point, I'm trying to define an XML Schema that looks as following: 为了弄清楚这一点,我试图定义一个如下所示的XML模式:

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

The keyCode is an enumeration type used to identify keyboard presses and it accepts a subset of xs:int . keyCode是用于识别键盘按下情况的枚举类型,它接受xs:int的子集。

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: 我的想法是,我不想验证将多个可能的动作映射到同一键的XML文件,因此以下XML应该无效:

<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. 用于移动方向的所有属性和用于其他动作的所有元素都应该是唯一的。

Sadly, when I try to validate the given XML against the XSD, it is valid! 可悲的是,当我尝试针对XSD验证给定的XML时,它是有效的! 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). 我认为唯一标记中的XPath已损坏,但我不知道如何解决(我尝试了多种变体,包括<xs:field xpath="*/move/@*"/><xs:field xpath="*/wait"/>仍然无法正常运行)。

Thanks in advance! 提前致谢!

Edit: 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>

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. 我尝试在网上查找xpath示例,但找不到任何可帮助我识别问题的东西。 Thanks! 谢谢!

I don't think this can be done using XSD 1.0. 我认为使用XSD 1.0不能做到这一点。 Unique works this way: xs:selector selects a set of elements across wich the fields value should be unique. 唯一性的工作方式如下: xs:selector在整个字段值应该唯一的情况下选择一组元素。

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 | 请记住,在XPath中,运算符| 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>

However XSD does not allows to select attributes in xs:selector . 但是, XSD不允许在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: 但我希望您理解,如果NNEW等是元素而不是属性,则可以使用类似以下内容的方法,它将起作用:

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

And this will work because you are only selecting elements in xs:selector. 这将起作用,因为您仅在xs:selector中选择元素。

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). 使用XSD 1.1,可以使用xs:assert来完成,它允许您使用xpath(选择器,字段,唯一性等仅允许您使用受限的XPath子集)。 Example assertion that will solve this problem: 示例断言将解决此问题:

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

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. 此外,请记住,使用范围(从10到105)和使用并集(从10到50 +从60到105)更容易定义keyCode类型,而不是使用xs:enumeration。

Example for continuos values: 连续值的示例:

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

Example for non continuous values: 非连续值的示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM