XML Schema Facets

I have received a number of requests over a period of time asking how to get all the facets defined on simple types or complex types with simple content in an XML Schema. I recently wrote a code sample for the same and I thought i will post it for wider consumption. The code sample will handle restrictions on lists, unions as well as facets defined on base types.

 public static void GetSchemaTypeFacets(XmlSchemaType schemaType) {

  if (schemaType == null || schemaType.Datatype == null) { //Complex type with complex content
   return;
  }

  XmlSchemaSimpleType st = schemaType as XmlSchemaSimpleType;
  if (st != null) {
   GetSimpleTypeFacets(st);
  }
  else { //Complex type simple content
   XmlSchemaComplexType ct = schemaType as XmlSchemaComplexType;
   Debug.Assert(ct != null);
   XmlSchemaSimpleContent simpleContent = ct.ContentModel as XmlSchemaSimpleContent;
   Debug.Assert(simpleContent != null);
   XmlSchemaSimpleContentRestriction simpleRest = simpleContent.Content as XmlSchemaSimpleContentRestriction;
   if (simpleRest != null) { //Can also be simple content extension
    PrintFacets(simpleRest.Facets);
   }
   GetSchemaTypeFacets(ct.BaseXmlSchemaType);

  }
 }

 public static void GetSimpleTypeFacets(XmlSchemaSimpleType st) {
   if (st == null || st.QualifiedName.Namespace == XmlSchema.Namespace) { //Built-in type, no user-defined facets
     return;
   }
   switch(st.Datatype.Variety) {
    case XmlSchemaDatatypeVariety.List:
      XmlSchemaSimpleType itemType = (st.Content as XmlSchemaSimpleTypeList).BaseItemType;
      GetSimpleTypeFacets(itemType);
    break;
 
    case XmlSchemaDatatypeVariety.Union:
      XmlSchemaSimpleTypeUnion union = st.Content as XmlSchemaSimpleTypeUnion;
      foreach(XmlSchemaSimpleType stu in union.BaseMemberTypes) {
        GetSimpleTypeFacets(stu);
      }
    break;

    case XmlSchemaDatatypeVariety.Atomic:
      XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;   
      PrintFacets(rest.Facets);
    break;

    default:
    break;  
  }

  if (st.BaseXmlSchemaType != null) { //Chain to the base type
   GetSimpleTypeFacets(st.BaseXmlSchemaType as XmlSchemaSimpleType); //BaseType of a simple type is always a simple type
  }
 
 }

 private static void PrintFacets(XmlSchemaObjectCollection facets) {
  foreach(XmlSchemaFacet facet in facets) {
   Console.WriteLine(facet.GetType().ToString() + " " + facet.Value);
  }    
 }

Let me know if you have any questions.

-Priya Lakshminarayanan