cdm/src/main/java/thredds/client/catalog/builder/CatalogBuilder.java
protected Service readService(Element s) {
    String name = s.getAttributeValue("name");
    String typeS = s.getAttributeValue("serviceType");
    String serviceBase = s.getAttributeValue("base");
    String suffix = s.getAttributeValue("suffix");
    String desc = s.getAttributeValue("desc");
    String accessType = s.getAttributeValue("accessType");

    ServiceType type = ServiceType.getServiceTypeIgnoreCase(typeS);
    if (type == null) {
      errlog.format(" non-standard service type = '%s'%n", typeS);
      logger.debug(" non-standard service type = '{}'", typeS);
    }
    else {
      if (desc == null) {
        desc = type.getDescription();
      }
      if (accessType == null) {
        accessType = type.getAccessType();
      }
    }

    List<Property> properties = null;
    List<Element> propertyList = s.getChildren("property", Catalog.defNS);
    for (Element e : propertyList) {
      if (properties == null) {
        properties = new ArrayList<>();
      }
      properties.add(readProperty(e));
    }

    // nested services
    List<Service> services = null;
    java.util.List<Element> serviceList = s.getChildren("service", Catalog.defNS);
    for (Element e : serviceList) {
      if (services == null) {
        services = new ArrayList<>();
      }
      services.add(readService(e));
    }

    Service result = new Service(name, serviceBase, typeS, desc, suffix, services, properties, accessType);
    serviceMap.put(name, result);
    return result;
  }
protected Service readService(Element s) {
    String name = s.getAttributeValue("name");
    String typeS = s.getAttributeValue("serviceType");
    String serviceBase = s.getAttributeValue("base");
    String suffix = s.getAttributeValue("suffix");
    String desc = s.getAttributeValue("desc");
    String accessType = s.getAttributeValue("accessType");

    ServiceType type = ServiceType.getServiceTypeIgnoreCase(typeS);
    if (type == null) {
      errlog.format(" non-standard service type = '%s'%n", typeS);
      logger.debug(" non-standard service type = '{}'", typeS);
    }
    else {
      if (desc == null) {
        desc = type.getDescription();
      }
      if (accessType == null) {
        accessType = type.getAccessType();
      }
    }

    List<Property> properties = null;
    List<Element> propertyList = s.getChildren("property", Catalog.defNS);
    for (Element e : propertyList) {
      if (properties == null) {
        properties = new ArrayList<>();
      }
      properties.add(readProperty(e));
    }

    // nested services
    List<Service> services = null;
    java.util.List<Element> serviceList = s.getChildren("service", Catalog.defNS);
    for (Element e : serviceList) {
      if (services == null) {
        services = new ArrayList<>();
      }
      services.add(readService(e));
    }

    Service result = new Service(name, serviceBase, typeS, desc, suffix, services, properties, accessType);
    serviceMap.put(name, result);
    return result;
  }
/* <xsd:element name="service">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="property" minOccurs="0" maxOccurs="unbounded" />
<xsd:element ref="service" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>

<xsd:attribute name="name" type="xsd:string" use="required" />
<xsd:attribute name="base" type="xsd:string" use="required" />
<xsd:attribute name="serviceType" type="serviceTypes" use="required" />
<xsd:attribute name="desc" type="xsd:string"/>
<xsd:attribute name="accessType" type="xsd:string"/>
<xsd:attribute name="suffix" type="xsd:string" />
</xsd:complexType>
</xsd:element>