This is the second time I ask this question:
In an XML document (using Version 1.1) an element random
has two integers: An integer start
that normally only should have a range of value from min=1
and max=9
. And an integer end
that is always supposed to be bigger then start with a max value of max=10
. Being defined like this:
<xs:complexType name="random">
<xs:attribute name="start">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="9"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="end">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="2"/>
<xs:maxInclusive value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:assert test="@start le @end"/>
</xs:complexType>
But now in some rare cases when there is the attribute bigValue
in another element present, I want these integers to actually be able to have a much higher value. To achieve that I can have the element random
as a child-element of the complexType-item annotation
which is defined in the XSD-file like this:
<xs:complexType name="annotation" mixed="true">
<xs:sequence>
<xs:element name="random" type="random" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="annotation">
<xs:simpleType>
<xs:union memberTypes="comments dice"/>
</xs:simpleType>
</xs:attribute>
<---- INSERT ASSERT HERE ---->
</xs:complexType>
For example in a case where bigValue
is defined, start
is supposed to have a value of 20 and end
of 50:
<annotation extended='bigValue'/><random start='20' end='50'/>
Is there any way how to do that without having to change the value range of start
and end
(because in almost all other cases it is not supposed to be bigger than 9 or respectively 10). Can this be achieved with an assert for example? Or is this not possible at all and the better approach is to limit the max values by an assert if bigValue
is absent?
I already tried plenty of assertions like the following ones but all of them fail to compile, only throwing the "XPST0003 - Assertion XPath expression couldn't compile successfully"-error. Here is what I tried:
<xs:assert test="if exists(annotation/bigValue) or every $x in .//@random.start satisfies $x le 10"/>
<xs:assert test="exists(annotation/bigValue) or every $x in .//@random.start satisfies $x le 10"/>
<xs:assert test="if ((random) and (annotation) and exists(annotation/bigValue)) or every $x in .//@random.start satisfies $x le 10"/>
Additionally I tried a restructured assert for the case that the value of start and end are defined higher to begin with. But even though I found an assert that compiled, it broke the XML-document completely telling me on any element that the assertion evaluation didn not succeed so I had to delete it as well. The assert I used was:
<xs:assert test="if (random.start le 9) then (annotation.annotation = 'bigValue') else not(random.start le 9)"/>
So at this point I'm fairly clueless and confused how to do it. Can you please help me?
Your first and third xs:assert
attempts are clearly nonsense: an XPath if
expression needs parentheses around the condition and then
and else
clauses. The fact that you attempt this and have no idea why it's wrong casts serious doubt on how you are approaching the task - you seem to be trying to write code by trial and error, without using any reference material to guide you.
The second attempt is closer, but if you enter this as an XPath expression into the XPath box in Oxygen, it tells you what is wrong:
exists(annotation/bigValue) or every $x in .//@random.start satisfies $x le 10
Unexpected token 'every' at start of expression
It needs to be
exists(annotation/bigValue) or (every $x in .//@random.start satisfies $x le 10)
which is syntactically valid. However, I suspect you don't have an attribute called @random.start
, instead I suspect you were trying to refer to the @start
attribute of the random
element, which would be .//random/@start
.