使元素值唯一 [英] Making Element Values Unique

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

问题描述

我有一个小型 XML 项目,我正在为用 XML 制作的国际象棋游戏状态定义模式.这包括创建棋子元素并为这些棋子创建引用它们在 PGN(位置游戏符号)中的位置的子元素.

I have a small XML project I'm doing where I am defining a schema for a chess game state made in XML. This includes creating chess piece elements and creating child elements for these pieces that reference their position in PGN (positional game notation).

该文件继续定义国王、王后等及其职位.我如何确保位置标记中的值是唯一的,即一个棋子不能在 17 处有两个位置,因为在棋盘的同一个正方形上会有两个棋子.

The document continues by defining King, Queen etc and their position(s). How do I ensure that the value within the position tag is unique i.e., a pawn cannot have two positions at 17 as that would be having two pieces on the same square of the board.

<position>17</position>
<position>17</position>

我尝试使用唯一约束,但它吓坏了我在piece元素中有多个位置元素.如何使这些棋子的价值始终是唯一的,并且没有两个棋子可以共享相同的位置值?

I tried using a unique constraint but it freaked out at the fact that I have multiple position elements within the piece element. How do I make it so the value of these pieces is always unique and no two pieces can share the same position value?

因此,唯一约束的放置适用于同一块标签内的位置元素,但有没有办法对整个文档中的任何位置执行此操作.示例:

So the placement of the unique constraint works for position elements within the same piece tag, but is there a way to do it for any position throughout the whole document. Example:

<board-side name="white">
    <pieces>
        <piece name="Pawn" symbol="p">
            <position>12</position>

<board-side name="BLACK">
    <pieces>
        <piece name="Pawn" symbol="P">
            <position>17</position>

上述两个 XML 片段都在它们自己的板端标签中.有没有办法让我把黑板边的位置改为12,它会抛出一个唯一的约束错误,或者唯一的只对同一标签内的多个元素有效?

Both of the above XML fragments are within their own board-side tags. Is there a way to make it so that if I change the position of the BLACK board side to 12, it will throw a unique constraint error, or does unique only work for multiple elements within the same tag?

编辑 2:整个架构

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema id="chess_schema" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:simpleType name="ident">
        <xs:restriction base="xs:string">
            <xs:enumeration value="P" />
            <xs:enumeration value="p" />
            <xs:enumeration value="Q" />
            <xs:enumeration value="q" />
            <xs:enumeration value="R" />
            <xs:enumeration value="r" />
            <xs:enumeration value="N" />
            <xs:enumeration value="n" />
            <xs:enumeration value="B" />
            <xs:enumeration value="b" />
            <xs:enumeration value="K" />
            <xs:enumeration value="k" />
        </xs:restriction>
    </xs:simpleType>

    <xs:element name="game-state">
        <xs:complexType>
            <xs:sequence>

                <xs:element name="board-state">
                    <xs:complexType>
                        <xs:sequence>

                            <xs:element name="board-side" minOccurs="2" maxOccurs="2">
                                <xs:complexType>
                                    <xs:sequence>

                                        <xs:element name="pieces">
                                            <xs:complexType>
                                                <xs:sequence>

                                                    <xs:element name="piece" maxOccurs="6">
                                                        <xs:complexType>
                                                            <xs:sequence>

                                                                <xs:element name="position" minOccurs="0" maxOccurs="8" >
                                                                    <xs:simpleType>
                                                                        <xs:restriction base="xs:int">
                                                                            <xs:minInclusive value="11" />
                                                                            <xs:maxInclusive value="88" />
                                                                        </xs:restriction>
                                                                    </xs:simpleType>
                                                                </xs:element>

                                                            </xs:sequence>
                                                            <xs:attribute name="symbol" type="ident" />
                                                            <xs:attribute name="name" type="xs:string" />
                                                        </xs:complexType>
                                                    </xs:element>

                                                </xs:sequence>
                                            </xs:complexType>
                                        </xs:element>

                                        <xs:element name="taken-pieces" maxOccurs="1" minOccurs="0" type="xs:string" />

                                    </xs:sequence>
                                    <xs:attribute name="name" type="xs:string" />
                                </xs:complexType>
                            </xs:element>

                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

            </xs:sequence>
        </xs:complexType>

        <xs:unique name="uniquePos">
            <xs:selector xpath="board-side/pieces/piece/position" />
            <xs:field xpath="." />
        </xs:unique>

    </xs:element> <!--end game-state root-->
</xs:schema>

推荐答案

唯一性约束保证您的位置元素在指定的范围内是唯一的.

An uniqueness constraint guarantees that your position elements will be unique within a specified scope.

您应该在表示该范围的元素中定义约束.例如,如果范围是 piece 元素,您可以通过相对于该上下文的 XPath 选择器将其关联到 position 元素.

You should define the constraint in the element that represents that scope. If the scope is the piece element, for example, you can associate it to the position elements via a XPath selector relative to this context.

如果您没有目标命名空间,您可以简单地使用它而无需前缀:

If you have no target namespace you can simply use it without prefixes:

<xs:element name="piece">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="position" minOccurs="0" maxOccurs="8"/>
        </xs:sequence>
    </xs:complexType>
    <xs:unique name="uniquePos">
        <xs:selector xpath="position" />
        <xs:field xpath="." />
    </xs:unique>
</xs:element>

但是,如果您的架构具有目标命名空间,则必须使用前缀对其进行声明,因为 XPath 假定无前缀的名称属于无命名空间.所以你需要这样的东西:

If your schema has a target namespace, however, you must declare it with a prefix since XPath assumes that an unprefixed name belongs to no-namespace. So you need something like:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified"
           xmlns="ns1" xmlns:chess="ns1" targetNamespace="ns1">  ...

(您真的不需要将其复制为默认命名空间,除非您还在其他地方引用了非限定类型,但您需要带前缀的类型).

(you don't really need to duplicate it as the default namespace, unless you also refer to unqualified types somewhere else, but you need the prefixed one).

然后您可以为 XPath 选择器添加前缀:

Then you can prefix your XPath selectors:

<xs:unique name="uniquePos">
    <xs:selector xpath="chess:position" />
    <xs:field xpath="." />
</xs:unique>

更新考虑您的版本.

如果您想增加唯一性约束有效的范围,您只需将声明放在该范围内.例如,如果您希望位置在整个 game-state 元素中是唯一的,您可以在那里声明:

If you want to increase the scope where your uniqueness constraint is valid, you just have to place the declaration in that scope. For example, if you want the positions to be unique within the entire game-state element, you can declare it there:

<xs:element name="game-state">
    ...
    <xs:unique name="uniquePos">
        <xs:selector xpath="/board-state/board-side/pieces/piece/position" />
        <xs:field xpath="." />
    </xs:unique>
</xs:element>

如果在 game-state 下的任何上下文中有两个具有相同值的 position 元素,这将导致验证错误.您也可以将它放在其他地方,只要 XPath 表达式在该上下文中有效.例如,在 board-state 中它会是:

This will cause a validation error if there are two position elements with the same value in any context below game-state. You can also put it in other places, as long as the XPath expression is valid in that context. For example, in board-state it would be:

<xs:element name="board-state">
    ...
    <xs:unique name="uniquePos">
        <xs:selector xpath="board-side/pieces/piece/position" />
        <xs:field xpath="." />
    </xs:unique>
</xs:element>

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

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