Как написать тестовые утверждения утверждения, чтобы ограничить значение элемента, чье происхождение не ограничено, используя значения значений элемента двоюродного брата и basi c math - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь написать схему XML, которая налагает строгие ограничения на значения элементов, основанные на небольшом математическом значении со значениями элементов двоюродного брата. Ниже приведен пример схемы и XML файла, иллюстрирующих правила, которые я пытаюсь навязать.

Схема:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
    <xs:element name="payload">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="param" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element ref="bitLength"/> <!-- see below -->
                            <xs:element name="offsetBytes" type="xs:nonNegativeInteger"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <!-- These are the basic rules I want to have -->
            <xs:assert test="param[1]/offsetBytes = 0"/>
            <xs:assert test="param[2]/offsetBytes = param[1]/offsetBytes + ceiling(param[1]/bitLength div 8)"/>
            <xs:assert test="param[3]/offsetBytes = param[2]/offsetBytes + ceiling(param[2]/bitLength div 8)"/>
            <xs:assert test="param[4]/offsetBytes = param[3]/offsetBytes + ceiling(param[3]/bitLength div 8)"/>
            <!-- and so on ... -->
        </xs:complexType>
    </xs:element>
    <xs:element name="bitLength">
        <xs:simpleType>
            <xs:restriction base="xs:positiveInteger">
                <xs:maxInclusive value="32"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
</xs:schema>

XML:

<?xml version="1.0" encoding="UTF-8"?>
<payload xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="file:ExampleProblem.xsd">
    <param>
        <bitLength>1</bitLength>
        <offsetBytes>0</offsetBytes>
    </param>
    <param>
        <bitLength>30</bitLength>
        <offsetBytes>1</offsetBytes>
    </param>
    <param>
        <bitLength>16</bitLength>
        <offsetBytes>5</offsetBytes>
    </param>
    <param>
        <bitLength>12</bitLength>
        <offsetBytes>7</offsetBytes>
    </param>
</payload>

Этот XML файл правильно проверяет соответствие схеме, но обратите внимание, что в схеме param есть minOccurs="0" и maxOccurs="unbounded". Как написано, операторы проверки утверждения имеют несколько нежелательных эффектов / недостатков:

  1. Файл XML, содержащий менее 4 param элементов, не пройдет проверку.
  2. An XML файл, содержащий более 4 param элементов, не подчиняется правилам, которые я хотел бы навязать, потому что нет никаких утверждений теста assert, которые ограничивают их значения.

Как я могу написать набор операторы assert test, которые допускают любое количество элементов param и подчиняются строгим правилам значений, которые я хочу?

Я думаю, что можно заменить все операторы assert test в приведенной выше схеме на 2 оператора assert test:

<xs:assert test="
    if (param) 
    then param[1]/offsetBytes = 0
    else true()"/>
<xs:assert test="
    if (param[2])
    then 
        for $a in (2 to count(param))
        return param[$a]/offsetBytes = param[$a-1]/offsetBytes + ceiling(param[$a-1]/bitLength div 8)
    else true()"/>

Первый из приведенных выше имеет желаемое поведение. Второй нет, но, надеюсь, он достаточно близко, чтобы вы могли видеть, к чему я стремился. Кто-нибудь может помочь?

...