问题
I would like to ask if someone knows how to make an XSD 1.1 Conditional Type Assignment check if an element hasn't an attribute using the XPath query, e.g.:
<!--inline alternative type definitions -->
<element name="TimeTravel" type="TravelType">
<alternative test="@direction='Future'">
<complexType>
<complexContent>
<restriction base="TravelType"
....
<!-- some past travel related elements go here -->
</complexType>
</alternative>
<alternative test="@direction='Past'">
<complexType>
<complexContent>
<restriction base="TravelType"
....
<!-- some future travel related elements go here -->
</complexType>
</alternative>
</element>
OR
<!--Named alternative type definitions -->
<element name="TimeTravel" type="TravelType">
<alternative test="@direction='Future' type="FutureTravelType"/>
<alternative test="@direction='Past' type="PastTravelType"/>
</element>
In this example the 'alternative test=""' checks whether the attribute "direction" of the TimeTravel element has a value of "Future" or "Past". How should I write the XPath query to check if e.g. there's no "direction" attribute for the current element?
回答1:
The XPath "@direction"
will test for the presence of a direction
attribute on the current element:
<alternative test="@direction" type="DirectionType"/>
The XPath "not(@direction)"
will test for the absence of a direction
attribute on the current element:
<alternative test="not(@direction)" type="NoDirectionType"/>
Note also that the alternative/@test
attribute can be omitted altogether to provide a default type.
<alternative type="DefaultType"/>
Update to address CTA subset mode per OP's follow-up question
So this
<alternative test="@direction='a_value' and not(@another_attribute)"/>
is correct and would make it right?
Yes, but be aware that your XSD processor may use the XPath CTA (Conditional Type Assignment) subset by default. (Xerces, and therefore most Xerces-based tools, do this, for example.) If this is the case, you will get an error that looks something like this:
c-cta-xpath: The XPath expression 'not(@direction)' couldn't compile successfully in 'cta-subset' mode, during CTA evaluation.
c-cta-xpath: The XPath expression '@direction='a_value' and not(@another_attribute)' couldn't compile successfully in 'cta-subset' mode, during CTA evaluation.
To use full XPath 2.0 rather than the CTA subset, configure your tool accordingly. For example, for Xerces, set the following feature to 'true':
http://apache.org/xml/features/validation/cta-full-xpath-checking
In oXygen, there's a checkbox in Options > Preferences > XML > XML Parser > XML Schema
that will control the value of the feature for you.
Using full XPath 2.0, yes, you can use and
in the manner you suggest in your comment.
来源:https://stackoverflow.com/questions/25191397/xsd-1-1-conditional-type-assignment-alternative-test-to-check-if-an-element