3

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?

tonix
  • 6,671
  • 13
  • 75
  • 136

1 Answers1

7

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.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • Thank you for your explanatory response, just another question, if for example I need to check that the element has an attribute with a particular value and at the same time check if another attribute is absent what can I do? – tonix Aug 07 '14 at 20:45
  • 2
    You can use [**boolean expressions**](http://www.w3.org/TR/xpath/#booleans) to build up more complicated conditions using `and`, `or`, and `not`. – kjhughes Aug 07 '14 at 21:05
  • Thanks for the link! So this `` is correct and would make it right? – tonix Aug 07 '14 at 21:36
  • I am sorry for my ignorance, but what does CTA mean in XPath CTA? Surfed the net but didn't find anything. – tonix Aug 08 '14 at 07:59
  • 1
    **CTA** is [**Conditional Type Assignment**](http://www.w3.org/TR/xmlschema11-1/#cTypeAlternative). – kjhughes Aug 08 '14 at 11:42