Effects of the type substitution mechanism on static typing (part II)

In this follow-up to last week’s post I’d like to look at more examples, in particular those involving the use of wildcards in XPath expressions.

Let’s look at the following schema

CREATE XML SCHEMA COLLECTION myCollection AS '
<schema xmlns="https://www.w3.org/2001/XMLSchema"
targetNamespace="https://ns"
xmlns:ns="https://ns">

 <complexType name="myType">
<choice minOccurs="0">
<element name="s1" type="string"/>
<element name="s2" type="string"/>
</choice>
</complexType>

 <element name="root" type="ns:myType"/>

</schema>'
go

Now let’s write a query that returns the string value of the first child of ‘root’ minus its first two characters

DECLARE @var XML(myCollection)
SET @var = '<x:root xmlns:x="https://ns"><s2>This is a string</s2></x:root>'
SELECT @var.query('declare namespace ns="https://ns"; substring((/ns:root/*)[1],3)')
go

You’ll notice that since we don’t know whether the first child of a ‘root’ element’ will be ‘s1’ or ‘s2’ we used a wildcard in the XPath expression. This doesn’t matter since both ‘s1’ and ‘s2’ are of type xs:string. This query will compile and returns
is is a string

Now let’s add some components to our schema

ALTER XML SCHEMA COLLECTION myCollection ADD '
<schema xmlns="https://www.w3.org/2001/XMLSchema"
targetNamespace="https://ns"
xmlns:ns="https://ns">

 <import namespace="https://ns"/>

 <complexType name="mySubType1">
<complexContent>
<extension base="ns:myType">
<sequence>
<element name="b" type="integer"/>
</sequence>
<attribute name="a1" type="string"/>
</extension>
</complexContent>
</complexType>

 <complexType name="mySubType2">
<complexContent>
<extension base="ns:myType">
<sequence>
<element name="b" type="integer"/>
</sequence>
<attribute name="a2" type="string"/>
</extension>
</complexContent>
</complexType>

</schema>
'
go

If we try to run our query again, this time it will fail with the following error message

XQuery [query()]: Cannot implicitly convert from '(xs:integer | xs:string) ?' to 'xs:string ?'

The problem is that we’ve added 2 types derived from ‘myType’ to the schema and because of the type substitution mechanism, the first child of element ‘root’ can be ‘s1’, ‘s2’ or ‘b’. Element ‘b’ being of type xs:integer in both derived types, the static type of expression data((/ns:root/*)[1]) is (xs:integer | xs:string) ?
Since the string-length function requires the type of its first parameter to be xs:string?,compilation fails and an error is returned.

 

-
Disclaimer:
This posting is provided “AS IS” with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at https://www.microsoft.com/info/cpyright.htm.