public XmlQueryType ChildrenOf(XmlQueryType source, XmlQueryType filter) {
Debug.Assert(filter.IsNode && filter.Count == 1 && filter.IsSingleton);
List<XmlQueryType> list = new List<XmlQueryType>();
XmlQueryCardinality card = XmlQueryCardinality.None;
foreach (XmlQueryType sourceItem in source) {
switch (sourceItem.TypeCode) {
case XmlTypeCode.Node:
case XmlTypeCode.Document:
case XmlTypeCode.Element:
XmlSchemaType sourceSchemaType = sourceItem.SchemaType;
XmlQueryCardinality itemCard = XmlQueryCardinality.None;
// Only element and document can have children
if (sourceSchemaType == XmlSchemaComplexType.UntypedAnyType) {
// content of xdt:untypedAny is element(*, xdt:untypedAny)*
itemCard = (AddFilteredPrime(list, UntypedElement, filter) * XmlQueryCardinality.ZeroOrMore);
itemCard += AddFilteredPrime(list, Text, filter);
}
else if (sourceSchemaType.Datatype != null) {
// Text is the only child node simple type can have
itemCard = AddFilteredPrime(list, Text, filter, true) * XmlQueryCardinality.ZeroOrOne;
}
else {
// Complex content
XmlSchemaComplexType complexType = (XmlSchemaComplexType)sourceSchemaType;
itemCard = AddChildParticle(list, complexType.ContentTypeParticle, filter);
if (complexType.ContentType == XmlSchemaContentType.Mixed) {
itemCard += AddFilteredPrime(list, Text, filter);
}
}
itemCard += AddFilteredPrime(list, PI, filter);
itemCard += AddFilteredPrime(list, Comment, filter);
card |= itemCard;
break;
case XmlTypeCode.Attribute:
case XmlTypeCode.ProcessingInstruction:
case XmlTypeCode.Comment:
case XmlTypeCode.Namespace:
case XmlTypeCode.Text:
card |= XmlQueryCardinality.Zero;
break;
default:
Debug.Assert(sourceItem.IsAtomicValue, "missed case for a node");
return null;
}
}
// Make sure that cardinality is at least Zero
return PrimeProduct(ChoiceType.Create(list), source.Cardinality * card);
}