public XmlQueryType DataOn(XmlQueryType source) {
List<XmlQueryType> list = new List<XmlQueryType>();
XmlQueryCardinality card = XmlQueryCardinality.None;
foreach (XmlQueryType sourceItem in source) {
switch (sourceItem.TypeCode) {
case XmlTypeCode.Item:
case XmlTypeCode.Node:
AddItemToChoice(list, AnyAtomicType);
card = XmlQueryCardinality.ZeroOrMore;
break;
case XmlTypeCode.Document:
case XmlTypeCode.Text:
AddItemToChoice(list, UntypedAtomic);
card |= XmlQueryCardinality.One;
break;
case XmlTypeCode.Comment:
case XmlTypeCode.ProcessingInstruction:
AddItemToChoice(list, String);
card |= XmlQueryCardinality.One;
break;
case XmlTypeCode.Element:
case XmlTypeCode.Attribute:
XmlSchemaType sourceSchemaType = sourceItem.SchemaType;
if (sourceSchemaType == XmlSchemaComplexType.UntypedAnyType || sourceSchemaType == DatatypeImplementation.UntypedAtomicType) {
AddItemToChoice(list, UntypedAtomic);
card |= XmlQueryCardinality.One;
}
else if (sourceSchemaType == XmlSchemaComplexType.AnyType || sourceSchemaType == DatatypeImplementation.AnySimpleType) {
AddItemToChoice(list, AnyAtomicType);
card = XmlQueryCardinality.ZeroOrMore;
}
else {
if (sourceSchemaType.Datatype == null) {
// Complex content adds anyAtomicType* if mixed
XmlSchemaComplexType complexType = (XmlSchemaComplexType)sourceItem.SchemaType;
if (complexType.ContentType == XmlSchemaContentType.Mixed) {
AddItemToChoice(list, AnyAtomicType);
card = XmlQueryCardinality.ZeroOrMore;
}
else {
// Error if mixed is false
return null;
}
}
else {
// Simple content
XmlSchemaType schemaType = sourceItem.SchemaType;
// Go up the tree until it's a simple type
while (schemaType is XmlSchemaComplexType) {
schemaType = schemaType.BaseXmlSchemaType;
}
// Calculate XmlQueryType from XmlSchemaSimpleType
XmlQueryType atomicSeq = Type((XmlSchemaSimpleType)schemaType, false);
// Add prime to a choice
// It doen't have to be a single item!
PrimeChoice(list, atomicSeq.Prime);
// Add cardinality to a choice
card |= atomicSeq.Cardinality;
}
// Add ? if nillable
if (sourceItem.IsNillable) {
card *= XmlQueryCardinality.ZeroOrOne;
}
}
break;
case XmlTypeCode.Namespace:
card |= XmlQueryCardinality.Zero;
break;
case XmlTypeCode.None:
break;
default:
Debug.Assert(sourceItem.IsAtomicValue, "missed case for a node");
AddItemToChoice(list, sourceItem);
card |= XmlQueryCardinality.One;
break;
}
}
return PrimeProduct(ChoiceType.Create(list), source.Cardinality * card);
}