module model_xml use FoX_DOM use validation implicit none !xml tag constants for easier modification later character (len = *), parameter :: tag_name = "name" character (len = *), parameter :: tag_parameters = "parameters" character (len = *), parameter :: tag_parameter = "parameter" character (len = *), parameter :: tag_value = "value" character (len = *), parameter :: tag_series = "series" character (len = *), parameter :: tag_multidim = "multidim" ! character (len=*), parameter :: tag_notes = "notes" ! character (len=*), parameter :: tag_history = "history" ! character (len=*), parameter :: tag_extensions = "extensions" ! character (len=*), parameter :: tag_reference = "reference" ! !xml attribute constants character (len = *), parameter :: attr_name = "name" character (len = *), parameter :: attr_units = "units" character (len = *), parameter :: attr_format = "format" character (len = *), parameter :: attr_meta = "meta" contains ! parses a version attribute. Returns 0 if attribute is not defined function parseModelVersion(np, attr) real :: parseModelVersion character (len = *) :: attr type(Node), pointer :: np, ap ap => getAttributeNode(np, attr) if(associated(ap)) then !the attribute exists, parse as a real call extractDataAttribute (np, attr, parseModelVersion) else !the attribute does not exist, return 0 parseModelVersion = 0 end if end function subroutine parseModelVersions(np, format, meta) real, optional :: format, meta type(Node), pointer :: np if(present(format)) then format = parseModelVersion(np, attr_format) end if if(present(meta)) then meta = parseModelVersion(np, attr_meta) end if end subroutine !parse the name of the model object subroutine parseModelName(np, name, format) type(Node), pointer :: np, p real, intent(in) :: format character(len=*) :: name p => item(getElementsByTagName(np, "name"), 0) if(associated(p)) then call extractDataContent(p, name) else print *, "ERROR: name element is required." stop 1 end if end subroutine subroutine verifyModelFormatVersion(format) real, intent(in) :: format if(.not.checkRange(format, minin=2.0, maxex=3.0)) then print *, "ERROR: Invalid xml format version", format stop 1 end if end subroutine subroutine verifyModelParameterCount(series_count, max_series_count,& value_count, max_value_count, dim_count, max_dim_count) integer, intent(in), optional :: series_count, max_series_count,& value_count, max_value_count, dim_count, max_dim_count if (present(series_count) .and. present(max_series_count)) then if(.not.checkRange(series_count, maxin=max_series_count)) then print *, "ERROR: series count out of range.", series_count stop 1 end if end if if (present(value_count) .and. present(max_value_count)) then if(.not.checkRange(value_count, maxin=max_value_count)) then print *, "ERROR: value count out of range.", value_count stop 1 end if end if if (present(dim_count) .and. present(max_dim_count)) then if(.not.checkRange(dim_count, maxin=max_dim_count)) then print *, "ERROR: dim count out of range.", dim_count stop 1 end if end if end subroutine subroutine verifyElementCount(np, tag, min, max) type(Node), pointer :: np character(len=*), intent(in) :: tag integer, intent(in), optional :: min, max integer :: count type(NodeList), pointer :: list list => getElementsByTagName(np, tag, recursive=.false.) count = getLength(list) if(present(min)) then if (count .lt. min) then print *, "ERROR: element count out of range. ",tag, count stop 1 end if end if if(present(max)) then if (count .gt. max) then print *, "ERROR: element count out of range. ",tag, count stop 1 end if end if end subroutine ! function getDirectElementsByTagName(doc, tagName, name, ex)result(list) ! type(DOMException), intent(out), optional :: ex ! type(Node), pointer :: doc ! character(len=*), intent(in), optional :: tagName, name ! type(NodeList), pointer :: list ! ! type(Node), pointer :: temp ! integer :: i ! ! ! ! list => getElementsByTagName(doc, tagName, name, ex) ! ! i = 0 ! do while (i .lt. getLength(list)) ! if(.not.associated (getParentNode(item(list,i)), doc)) then ! print *, "remove" ! temp => remove_nl(list, i) ! else ! i = i + 1 ! end if ! end do ! ! end function end module