I have the following XML Schema:
CREATE XML SCHEMA COLLECTION test AS '
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="PointConf">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="GlobalFlags">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Order" type="OrderType"/>
<xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="OrderType">
<xsd:attribute name="value" type="xsd:int" />
</xsd:complexType>
</xsd:schema>
'
GO
Then I use it in this way:
DECLARE @xml xml(test)
SET @xml='<PointConf>
<GlobalFlags>
<Order value="1" />
</GlobalFlags>
</PointConf>'
SELECT @xml.value('(/PointConf/GlobalFlags/Order/@value)[1]','int')
SELECT gives me the following error:
XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type '(xs:int | xdt:anyAtomicType *) ?'
Without the xsd:any element in the schema the code above works without any errors. What am I doing wrong?
I got the select to work by using the statement
I understand the requirement for the
[1]index on the Order node, as this can be a list, however I don’t see why its required for thePointConfnode.The
[1]needs to be used at the actual level where a list exists to restrict that list to a single return valueThe
string(...)turns the node set into a string (or empty string). I think this helps with thexsd:anyalthough I’m not completely sure why – something to do with handling the possibility of the nodeOrderbeing missing completely I think.Update:
Investigating further:
SELECT @xml.value('string((/PointConf/GlobalFlags/Order/@value)[1])','int')also works.
So its just the string function that’s required to make it work in this instance.