xmerl_xsd_type.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,562 行 · 第 1/3 页
ERL
1,562 行
%% gMonthDay on the form: mm dd zzzzzz?check_gMonthDay("--"++Value) -> {M,"-"++DTZ} = lists:split(2,Value), {ok,_} = check_month(M), {ok,_} = check_gDay2(DTZ).%% dDay on the form dd zzzzzz?check_gDay("---"++Value) -> check_gDay2(Value).check_gDay2(Value) -> {D,TZ} = lists:split(2,Value), {ok,_} = check_day(D), case TZ of [] -> {ok,Value}; _ -> {ok,_} = check_timezone(TZ) end.%% dMonth on the form mm zzzzzz?check_gMonth("--"++Value) -> {M,TZ} = lists:split(2,Value), {ok,_} = check_month(M), case TZ of [] -> {ok,Value}; _ -> {ok,_} = check_timezone(TZ) end.check_base64Binary(Value) -> case catch xmerl_b64Bin:parse(xmerl_b64Bin_scan:scan(Value)) of {ok,_} -> {ok,Value}; Err = {error,_} -> Err; {'EXIT',{error,Reason}} -> %% scanner failed on character {error,Reason}; {'EXIT',Reason} -> {error,{internal_error,Reason}} end.%% tokens may not contain the carriage return (#xD), line feed (#xA)%% nor tab (#x9) characters, that have no leading or trailing spaces%% (#x20) and that have no internal sequences of two or more spaces.check_token(V=[32|_]) -> {error,{invalid_token,leading_space,V}};check_token(Value) -> check_token(Value,Value).check_token([],Value) -> {ok,Value};check_token([32],V) -> {error,{invalid_token,trailing_space,V}};check_token([9|_T],V) -> {error,{invalid_token,tab,V}};check_token([10|_T],V) -> {error,{invalid_token,line_feed,V}};check_token([13|_T],V) -> {error,{invalid_token,carriage_return,V}};check_token([32,32|_T],V) -> {error,{invalid_token,double_space,V}};check_token([_H|T],V) -> check_token(T,V).%% conform to the pattern [a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*check_language(Value) -> check_language(Value,0).check_language([H|T],N) when H>=$A,H=<$Z -> check_language(T,N+1);check_language([H|T],N) when H>=$a,H=<$z -> check_language(T,N+1);check_language([$-|T],N) when N>=1,N=<8 -> check_language2(T,0);check_language([],N) when N>=1,N=<8 -> {ok,[]}.check_language2([H|T],N) when H>=$A,H=<$Z -> check_language2(T,N+1);check_language2([H|T],N) when H>=$a,H=<$z -> check_language2(T,N+1);check_language2([H|T],N) when H>=$0,H=<$9 -> check_language2(T,N+1);check_language2([$-|T],N) when N>=1,N=<8 -> check_language2(T,0);check_language2([],N) when N>=1,N=<8 -> {ok,[]}.check_NMTOKEN([H|T]) -> true = xmerl_lib:is_namechar(H), check_NMTOKEN2(T).check_NMTOKEN2([]) -> {ok,[]};check_NMTOKEN2([H|T]) -> true = xmerl_lib:is_namechar(H), check_NMTOKEN2(T).check_NMTOKENS(Value) -> TokList = string:tokens(Value," "), lists:foreach(fun check_NMTOKEN/1,TokList), {ok,Value}.check_Name(Value) -> true = xmerl_lib:is_name(Value), {ok,Value}.check_NCName(Value) -> true = xmerl_lib:is_ncname(Value), {ok,Value}.check_ID(Value) -> %% ID must be a NCName and uniquely identify the element which %% bear it. Only one ID per element. true = xmerl_lib:is_ncname(Value), {ok,Value}.check_IDREF(Value) -> true = xmerl_lib:is_name(Value), {ok,Value}.check_IDREFS(Value) -> check_list_type(Value,fun check_IDREF/1). check_ENTITY(Value) -> true = xmerl_lib:is_ncname(Value), {ok,Value}.check_ENTITIES(Value) -> check_list_type(Value,fun check_ENTITY/1).check_list_type(Value,BaseTypeFun) -> Tokens = string:tokens(Value," "), lists:foreach(BaseTypeFun,Tokens), {ok,Value}.ns_whitespace(WS) when WS==16#9;WS==16#A;WS==16#D -> true;ns_whitespace(_) -> false. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% facet functions%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%facet_fun(Type,{length,V}) -> length_fun(Type,list_to_integer(V));facet_fun(Type,{minLength,V}) -> minLength_fun(Type,list_to_integer(V));facet_fun(Type,{maxLength,V}) -> maxLength_fun(Type,list_to_integer(V));facet_fun(Type,{pattern,V}) ->%% fun(Val) ->%% {ok,Val}%% end; pattern_fun(Type,V);facet_fun(Type,{enumeration,V}) -> enumeration_fun(Type,V);facet_fun(Type,{whiteSpace,V}) -> whiteSpace_fun(Type,V);facet_fun(Type,{maxInclusive,V}) -> maxInclusive_fun(Type,V);facet_fun(Type,{maxExclusive,V}) -> maxExclusive_fun(Type,V);facet_fun(Type,{minExclusive,V}) -> minExclusive_fun(Type,V);facet_fun(Type,{minInclusive,V}) -> minInclusive_fun(Type,V);facet_fun(Type,{totalDigits,V}) -> totalDigits_fun(Type,list_to_integer(V));facet_fun(Type,{fractionDigits,V}) -> fractionDigits_fun(Type,list_to_integer(V));facet_fun(Type,F) -> fun(_X_) -> io:format("Warning: not valid facet on ~p ~p~n",[Type,F]) end.length_fun(T,V) when T==string;T==normalizedString;T==token; T=='Name';T=='NCName';T==language;T=='ID'; T=='IDREF';T=='IDREFS';T=='ENTITY';T=='ENTITIES'; T=='NMTOKEN';T=='NMTOKENS';T==anyURI -> fun(Val) -> case string:len(Val) == V of true -> {ok,Val}; false -> {error,{length,string:len(Val),should_be,V}} end end;length_fun(T,_V) when T=='NOTATION';T=='QName' -> fun(Val) -> {ok,Val} end;length_fun(T,V) when T==base64Binary;T==hexBinary -> fun(Val) -> case length(Val)==V of true -> {ok,Val}; false -> {error,{length,length(Val),xhould_be,V}} end end;length_fun(T,_V) -> fun(_Val) -> {error,{length_not_applicable_on,T}} end.minLength_fun(T,V) when T==string;T==normalizedString;T==token; T=='Name';T=='NCName';T==language;T=='ID'; T=='IDREF';T=='IDREFS';T=='ENTITY';T=='ENTITIES'; T=='NMTOKEN';T=='NMTOKENS';T==anyURI -> fun(Val) -> case string:len(Val) >= V of true -> {ok,Val}; false -> {error,{minLength,string:len(Val),should_at_least_be,V}} end end;minLength_fun(T,_V) when T=='NOTATION';T=='QName' -> fun(Val) -> {ok,Val} end;minLength_fun(T,V) when T==base64Binary;T==hexBinary -> fun(Val) -> case length(Val) >= V of true -> {ok,Val}; false -> {error,{minLength,length(Val),should_at_least_be,V}} end end;minLength_fun(T,_V) -> fun(_Val) -> {error,{minLength_not_applicable_on,T}} end.maxLength_fun(T,V) when T==string;T==normalizedString;T==token; T=='Name';T=='NCName';T==language;T=='ID'; T=='IDREF';T=='IDREFS';T=='ENTITY';T=='ENTITIES'; T=='NMTOKEN';T=='NMTOKENS';T==anyURI -> fun(Val) -> case length(Val) of Len when Len =< V -> {ok,Val}; _ -> {error,{maxLength,string:len(Val),should_not_be_more_than,V}} end end;maxLength_fun(T,_V) when T=='NOTATION';T=='QName' -> fun(Val) -> {ok,Val} end;maxLength_fun(T,V) when T==base64Binary;T==hexBinary -> fun(Val) -> case length(Val) =< V of true -> {ok,Val}; false -> {error,{maxLength,length(Val),should_not_be_more_than,V}} end end;maxLength_fun(T,_V) -> fun(_Val) -> {error,{maxLength_not_applicable_on,T}} end.pattern_fun(_Type,RegExp) -> case xmerl_regexp:setup(RegExp) of {ok,RE} -> fun(Val) -> case xmerl_regexp:first_match(Val,RE) of {match,_,_} -> {ok,Val}; _ -> {error,{pattern_mismatch,Val,RegExp}} end end; _ -> fun(Val) -> {error,{unsupported_pattern,Val,RegExp}} end end.enumeration_fun(_Type,V) -> fun(Val) -> case lists:member(Val,V) of true -> {ok,Val}; false -> {error,{enumeration,Val,should_be_one_of,V}} end end.whiteSpace_fun(_Type,"preserve") -> fun(Val) -> {ok,Val} end;whiteSpace_fun(_Type,"replace") -> fun(Val) -> {ok,?MODULE:replace_ws(Val,[])} end;whiteSpace_fun(_Type,"collapse") -> fun(Val) -> {ok,?MODULE:collapse_ws(Val)} end.replace_ws([16#9|T],Acc) -> replace_ws(T,[16#20|Acc]);replace_ws([16#a|T],Acc) -> replace_ws(T,[16#20|Acc]);replace_ws([16#d|T],Acc) -> replace_ws(T,[16#20|Acc]);replace_ws([H|T],Acc) -> replace_ws(T,[H|Acc]);replace_ws([],Acc) -> lists:reverse(Acc).collapse_ws(Val) -> collapse_ws(lists:dropwhile(fun(WS) when ?is_whitespace(WS) ->true;(_) -> false end, replace_ws(Val,[])),[]).collapse_ws([16#20,16#20|T],Acc) -> collapse_ws([16#20|T],Acc);collapse_ws([H|T],Acc) -> collapse_ws(T,[H|Acc]);collapse_ws([],Acc) -> lists:reverse(lists:dropwhile(fun($ ) ->true;(_) -> false end,Acc)). maxInclusive_fun(T,V) when T==integer;T==positiveInteger;T==negativeInteger; T==nonNegativeInteger;T==nonPositiveInteger;T==long; T==unsignedLong;T==int;T==unsignedInt;T==short; T==unsignedShort;T==byte;T==unsignedByte -> fun(Val) -> case (catch list_to_integer(Val) =< list_to_integer(V)) of true -> {ok,Val}; _ -> {error,{maxInclusive,Val,should_be_less_than_or_equal_with,V}} end end;maxInclusive_fun(T,V) when T==decimal;T==float;T==double -> fun(Val) -> case ?MODULE:compare_floats(Val,V) of gt -> {error,{maxInclusive,Val,should_be_less_than_or_equal_with,V}}; Err={error,_} -> Err; _ -> {ok,Val} end end;maxInclusive_fun(T,V) when T==duration -> fun(Val) -> case ?MODULE:compare_durations(Val,V) of GT when GT==gt;GT==indefinite -> {error,{maxInclusive,Val,should_be_less_than_or_equal_with,V}}; _ -> {ok,Val} end end;maxInclusive_fun(T,V) when T==dateTime -> fun(Val) -> case ?MODULE:compare_dateTime(Val,V) of GT when GT==gt;GT==indefinite -> {error,{maxInclusive,Val,should_be_less_than_or_equal_with,V}}; _ -> {ok,Val} end end;maxInclusive_fun(T,_V) ->%% when T==duration;T==dateTime;T==date;T==time;T==gYear;T==gYearMonth;%% T==gMonth;T==gMonthDay;T==gDay -> fun(_) -> {error,{maxInclusive,not_implemented_for,T}} end.maxExclusive_fun(T,V) when T==integer;T==positiveInteger;T==negativeInteger; T==nonNegativeInteger;T==nonPositiveInteger;T==long; T==unsignedLong;T==int;T==unsignedInt;T==short; T==unsignedShort;T==byte;T==unsignedByte -> fun(Val) -> case (catch list_to_integer(Val) < list_to_integer(V)) of true -> {ok,Val}; _ -> {error,{maxExclusive,Val,not_less_than,V}} end end;maxExclusive_fun(T,V) when T==decimal;T==float;T==double -> fun(Val) -> case ?MODULE:compare_floats(Val,V) of lt -> {ok,Val}; Err={error,_} -> Err; _ -> {error,{maxExclusive,Val,not_less_than,V}} end end;maxExclusive_fun(T,V) when T==duration -> fun(Val) -> case ?MODULE:compare_durations(Val,V) of lt -> {ok,Val}; _ -> {error,{maxExclusive,Val,not_less_than,V}} end end;maxExclusive_fun(T,V) when T==dateTime -> fun(Val) -> case ?MODULE:compare_dateTime(Val,V) of lt -> {ok,Val}; _ -> {error,{maxExclusive,Val,not_less_than,V}} end end;maxExclusive_fun(T,_V) -> fun(_) -> {error,{maxExclusive,not_implemented_for,T}} end.minExclusive_fun(T,V) when T==integer;T==positiveInteger;T==negativeInteger; T==nonNegativeInteger;T==nonPositiveInteger;T==long; T==unsignedLong;T==int;T==unsignedInt;T==short; T==unsignedShort;T==byte;T==unsignedByte -> fun(Val) -> case (catch list_to_integer(Val) > list_to_integer(V)) of true -> {ok,Val}; _ -> {error,{minExclusive,Val,not_greater_than,V}} end end;minExclusive_fun(T,V) when T==decimal;T==float;T==double -> fun(Val) -> case ?MODULE:compare_floats(Val,V) of gt -> {ok,Val}; Err={error,_} -> Err; _ -> {error,{minExclusive,Val,not_greater_than,V}} end end;minExclusive_fun(T,V) when T==duration -> fun(Val) -> case ?MODULE:compare_durations(Val,V) of gt -> {ok,Val}; _ -> {error,{minExclusive,Val,not_greater_than,V}} end end;minExclusive_fun(T,V) when T==dateTime -> fun(Val) -> case ?MODULE:compare_dateTime(Val,V) of gt -> {ok,Val}; _ -> {error,{minExclusive,Val,not_greater_than,V}} end end;minExclusive_fun(T,_V) -> fun(_) -> {error,{minExclusive,not_implemented_for,T}} end.minInclusive_fun(T,V) when T==integer;T==positiveInteger;T==negativeInteger; T==nonNegativeInteger;T==nonPositiveInteger;T==long; T==unsignedLong;T==int;T==unsignedInt;T==short; T==unsignedShort;T==byte;T==unsignedByte -> fun(Val) -> case (catch list_to_integer(Val) >= list_to_integer(V)) of true -> {ok,Val}; _ -> {error,{minInclusive,Val,not_greater_than_or_equal_with,V}} end end;minInclusive_fun(T,V) when T==decimal;T==float;T==double -> fun(Val) -> case ?MODULE:compare_floats(Val,V) of lt -> {error,{minInclusive,Val,not_greater_than_or_equal_with,V}}; Err={error,_} -> Err; _ -> {ok,Val} end end;minInclusive_fun(T,V) when T==duration -> fun(Val) -> case ?MODULE:compare_durations(Val,V) of lt -> {error,{minInclusive,Val,not_greater_than_or_equal_with,V}}; _ -> {ok,Val} end end;minInclusive_fun(T,V) when T==dateTime -> fun(Val) -> case ?MODULE:compare_dateTime(Val,V) of lt -> {error,{minInclusive,Val,not_greater_than_or_equal_with,V}}; _ -> {ok,Val} end end;minInclusive_fun(T,_V) -> fun(_) -> {error,{minInclusive,not_implemented_for,T}} end. totalDigits_fun(T,V) when T==integer;T==positiveInteger;T==negativeInteger;T==nonNegativeInteger; T==nonPositiveInteger;T==long;T==unsignedLong;T==int;T==unsignedInt; T==short;T==unsignedShort;T==byte;T==unsignedByte;T==decimal -> %% Val is expressible as i * 10^-n where i and n are integers %% such that |i| < 10^Val and 0 =< n =< Val. fun(Val) -> Pred = fun($0)-> true; (_) -> false end, Val2 = lists:dropwhile(Pred,Val), Length = case lists:member($.,Val2) of true -> length(lists:dropwhile(Pred,lists:reverse(Val2))) -1; _ -> length(Val2) end, if Length =< V -> {ok,Val}; true -> {error,{totalDigits,Length,to_many_digits}} end end;totalDigits_fun(T,_V) -> fun(_) -> {error,{totalDigits,not_applicable,T}} end. fractionDigits_fun(T,V) when T==integer;T==positiveInteger;T==negativeInteger;T==nonNegativeInteger;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?