Я пытаюсь написать схему 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"
. Как написано, операторы проверки утверждения имеют несколько нежелательных эффектов / недостатков:
- Файл XML, содержащий менее 4
param
элементов, не пройдет проверку. - 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()"/>
Первый из приведенных выше имеет желаемое поведение. Второй нет, но, надеюсь, он достаточно близко, чтобы вы могли видеть, к чему я стремился. Кто-нибудь может помочь?