cdm/src/main/java/thredds/client/catalog/builder/CatalogBuilder.java
protected ThreddsMetadata.VariableGroup readVariables( Element varsElem) {
    if (varsElem == null) {
      return null;
    }

    String vocab = varsElem.getAttributeValue("vocabulary");
    ThreddsMetadata.UriResolved variableVocabUri = readUri(varsElem, "Variables vocabulary");

    java.util.List<Element> vlist = varsElem.getChildren("variable", Catalog.defNS);
    ThreddsMetadata.UriResolved variableMap = readUri(varsElem.getChild("variableMap", Catalog.defNS), "Variables Map");
    if ((variableMap != null) && vlist.size() > 0) { // cant do both
      errlog.format(" ** Catalog error: cant have variableMap and variable in same element '%s'%n", varsElem);
    }

    List<ThreddsMetadata.Variable> variables = new ArrayList<>();
    for (Element e : vlist) {
      variables.add(readVariable(e));
    }

    return new ThreddsMetadata.VariableGroup(vocab, variableVocabUri, variableMap, variables);
  }
protected ThreddsMetadata.VariableGroup readVariables( Element varsElem) {
    if (varsElem == null) {
      return null;
    }

    String vocab = varsElem.getAttributeValue("vocabulary");
    ThreddsMetadata.UriResolved variableVocabUri = readUri(varsElem, "Variables vocabulary");

    java.util.List<Element> vlist = varsElem.getChildren("variable", Catalog.defNS);
    ThreddsMetadata.UriResolved variableMap = readUri(varsElem.getChild("variableMap", Catalog.defNS), "Variables Map");
    if ((variableMap != null) && vlist.size() > 0) { // cant do both
      errlog.format(" ** Catalog error: cant have variableMap and variable in same element '%s'%n", varsElem);
    }

    List<ThreddsMetadata.Variable> variables = new ArrayList<>();
    for (Element e : vlist) {
      variables.add(readVariable(e));
    }

    return new ThreddsMetadata.VariableGroup(vocab, variableVocabUri, variableMap, variables);
  }
/*
<xsd:element name="variables">
<xsd:complexType>
<xsd:choice>
<xsd:element ref="variable" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="variableMap" minOccurs="0"/>
</xsd:choice>
<xsd:attribute name="vocabulary" type="variableNameVocabulary" use="optional"/>
<xsd:attributeGroup ref="XLink"/>
</xsd:complexType>
</xsd:element>

<xsd:element name="variable">
<xsd:complexType mixed="true">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="vocabulary_name" type="xsd:string" use="optional"/>
<xsd:attribute name="vocabulary_id" type="xsd:string" use="optional"/>
<xsd:attribute name="units" type="xsd:string"/>
</xsd:complexType>
</xsd:element>

<xsd:element name="variableMap">
<xsd:complexType>
<xsd:attributeGroup ref="XLink"/>
</xsd:complexType>
</xsd:element>

<xsd:simpleType name="variableNameVocabulary">
<xsd:union memberTypes="xsd:token">
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="CF-1.0"/>
<xsd:enumeration value="DIF"/>
<xsd:enumeration value="GRIB-1"/>
<xsd:enumeration value="GRIB-2"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>