📄 xmerl_xsd.erl
字号:
S.get_circularity_mark({TD,_},S) when TD==simpleType;TD==complexType;TD==simple_or_complex_Type -> case S#xsd_state.circularity_stack of [From={typeDef,_}|_] -> From; _ -> [] end;get_circularity_mark(_,_S) -> [].push_circularity_mark(Mark,S=#xsd_state{circularity_stack=CS, redefine=false}) -> S#xsd_state{circularity_stack=[Mark|CS]};push_circularity_mark(_,S) -> S.pop_circularity_mark(Mark,S=#xsd_state{redefine=false}) -> case S#xsd_state.circularity_stack of [Mark|Rest] -> S#xsd_state{circularity_stack=Rest}; _ -> S end;pop_circularity_mark(_,S) -> S.derived_type({complexType,#schema_complex_type{name=Name,content=C}}, S=#xsd_state{derived_types=DT}) -> case {keymember(restriction,1,C),keymember(extension,1,C)} of {false,false} -> S; _ -> S#xsd_state{derived_types=[{complexType,Name}|DT]} end;derived_type({simpleType,#schema_simple_type{name=Name,content=C}}, S=#xsd_state{derived_types=DT}) -> case keymember(restriction,1,C) of true -> S#xsd_state{derived_types=[{simpleType,Name}|DT]}; _ -> S end.facets([{annotation,_}|Rest],S) -> facets(Rest,S);facets([{restriction,{BaseType,CM}}],_S) -> Facets = [X||X={F,_} <- CM,is_facet(F)], GroupFacets = group_facets(Facets), {BaseType,GroupFacets};facets(_,_S) -> {undefined,[]}.group_facets(Facets) -> group_facets(Facets,[]).group_facets(L=[{enumeration,_}|_Rest],Acc) -> {Enums,Rest} = splitwith(fun({enumeration,_}) -> true; (_) -> false end, L), group_facets(Rest,[{enumeration,[X||{enumeration,X}<-Enums]}|Acc]);group_facets([H|T],Acc) -> group_facets(T,[H|Acc]);group_facets([],Acc) -> reverse(Acc).simpleType_final(ST,_S) -> Final = get_attribute_value(final,ST,[]), split_by_whitespace(Final,[]).%% A redefine may contain (simpleType | complexType | group |%% attributeGroup)*%%{simpleType,Name},{complexType,Name},{group,Name},{attributeGroup,Name}redefine([CM|Rest],S) -> S2=redefine(CM,S), redefine(Rest,S2);redefine(ST={Type,_Name},S) when Type==simpleType ; Type==complexType -> %% Get the original definition {OriginalType,S2} = resolve(ST,S), %% unnecessary to delete saved object, it will be overwritten. {RedefinedType,S3} = load_redefine_object(ST,S2), {_MergedType,S4} = merge_derived_types(OriginalType,RedefinedType,redefine,S3), S4;redefine(_,S) -> %% attributeGroup and group redefines are already redefined S.keyrefer(keyref,El,S) -> Ref=get_attribute_value(refer,El,undefined), get_QName(Ref,El#xmlElement.namespace,reset_scope(S));keyrefer(_,_,_) -> undefined.remove_annotation(CM) when is_list(CM) -> [X||X = {K,_} <- CM, K=/=annotation].remove_attributes(CM) when is_list(CM) -> [X||X = {K,_} <- CM, K=/=attribute,K=/=anyAttribute,K=/=attributeGroup].keep_attributes(CM) when is_list(CM) -> [X||X = {K,_} <- CM, K==attribute orelse K==anyAttribute orelse K==attributeGroup].split_content([{restriction,{BaseT,CM}}]) -> {[{restriction,{BaseT,remove_attributes(CM)}}],keep_attributes(CM)};split_content([{extension,{BaseT,CM}}]) -> {[{extension,{BaseT,remove_attributes(remove_annotation(CM))}}], keep_attributes(CM)};split_content(CM) -> {remove_attributes(CM),keep_attributes(CM)}.restriction_base_type(R,CM,S) -> case base_type(R) of [] -> case [X||X={simpleType,_}<-CM] of [{simpleType,TypeName}] -> {TypeName,keydelete(simpleType,1,CM),S}; Other -> Err = {error_path(R,R#xmlElement.name),?MODULE, {missing_base_type,restriction,Other}}, {{[],[],[]},CM,acc_errs(S,Err)} end; BT -> {get_QName(BT,R#xmlElement.namespace,reset_scope(S)),CM,S} end. base_type([{restriction,{BaseT,_}}],SCT) -> SCT#schema_complex_type{base_type=BaseT};base_type([{extension,{BaseT,_}}],SCT) -> SCT#schema_complex_type{base_type=BaseT};base_type(_,SCT) -> SCT.variety([{list,_ItemType}]) -> list;variety([{union,_ItemType}]) -> union;variety(_) -> atomic.%% pre_check_cm/2 is for now only for simpleContent | complexContent%% which allow content: (annotation?, (restriction | extension))pre_check_cm(Kind,Cs=[C=#xmlElement{}|RestC],Name,S) -> case kind(C,S) of {annotation,_} -> pre_check_cm2(Kind,RestC,Name,C,S,0); {_,S2} -> pre_check_cm2(Kind,Cs,Name,C,S2,0) end;pre_check_cm(Kind,[_C|Cs],Name,S) -> pre_check_cm(Kind,Cs,Name,S);pre_check_cm(Kind,[],Name,S) -> Err = {[],?MODULE,{content_failure,Kind,[],Name}}, acc_errs(S,Err).pre_check_cm2(Kind,[C=#xmlElement{}|Cs],Name,_El,S,N) -> S2 = case kind(C,S) of {restriction,_} -> S; {extension,_} -> S; {Other,S1} -> Err = {error_path(C,C#xmlElement.name),?MODULE, {illegal_element,Kind,Other,Name}}, acc_errs(S1,Err) end, pre_check_cm2(Kind,Cs,Name,C,S2,N+1);pre_check_cm2(Kind,[_H|T],Name,El,S,N) -> pre_check_cm2(Kind,T,Name,El,S,N);pre_check_cm2(_,[],_,_,S,N) when N==1 -> S;pre_check_cm2(Kind,[],Name,El,S,N) -> Err = case N of 0 -> {error_path(El,El#xmlElement.name),?MODULE, {content_failure_expected_restriction_or_extension, Kind,Name}}; _ -> {error_path(El,El#xmlElement.name),?MODULE, {content_failure_only_one_restriction_or_extension_allowed, Kind,Name}} end, acc_errs(S,Err).%% check_cm(Arg1,Arg2,Arg3)%% Arg1 - The allowed content for this type according to schema for schemas%% Arg2 - The content model of this particular schemacheck_cm(Kind,S4SCM,ContentModel,S) -> case check_cm2(Kind,S4SCM,ContentModel,S) of {[],_S} -> S; {[_,[]|_],_S} -> S; {_CM,S2} -> S2; Err -> exit({error,{[],?MODULE,{internal_error,Err}}}) end.check_cm2(Kind,#chain{content=S4SCM,occurance=Occ}, ContentModel,S) -> case occurance_loop(Occ,fun check_chain/1, [S4SCM,ContentModel,Kind,S],0) of {ok,[]} -> {[],S}; {ok,[S4SCMRest,CMRest|_]} -> case all_optional(S4SCMRest) of true -> {CMRest,S}; _ -> Err = {[],?MODULE, {mandatory_component_missing,S4SCMRest,Kind}}, acc_errs(S,Err) end; {error,{_,_,Reason}} -> Err = {[],?MODULE,{illegal_content,Reason,Kind}}, {ContentModel,acc_errs(S,Err)} end;check_cm2(Kind,#alternative{content=S4SCM,occurance=Occ}, ContentModel,S) -> case occurance_loop(Occ,fun check_alternative/1, [S4SCM,ContentModel,Kind,S],0) of {ok,[]} -> {[],S}; {ok,[_,CMRest|_]} -> {CMRest,S}; {error,Reason} -> {ContentModel,acc_errs(S,Reason)} end;check_cm2(_,{Kind,Occ},CM,S) -> case occurance_loop(Occ,fun check_simple_cm/1,[Kind,CM],0) of {ok,[]} -> {[],S}; {ok,[_,CMRest|_]} -> {CMRest,S}; {error,Reason} -> {CM,acc_errs(S,Reason)}; Err -> {CM,acc_errs(S,Err)} end.%% check_simple_cmcheck_simple_cm([Kind,CM]) -> check_simple_cm(Kind,CM). check_simple_cm(Kind,[]) -> {error,{[],?MODULE,{no_match,{Kind,[]}}}};check_simple_cm(Kind,[{Kind,_}|Rest]) -> {ok,[Kind,Rest]};check_simple_cm(Kind,[{Other,_}|Rest]) when Kind==simpleType;Kind==complexType -> case Other of simple_or_complex_Type -> {ok,[Kind,Rest]}; _ -> {error,{[],?MODULE,{no_match,Other}}} end;check_simple_cm(_Kind,[{Other,_}|_]) -> {error,{[],?MODULE,{no_match,Other}}}.check_chain([S4SCM,ContentModel,Kind,S]) -> check_chain(Kind,S4SCM,ContentModel,S).check_chain(Kind,[S4SC|S4SCs],ChainCM=[_H|_T], S=#xsd_state{errors=Errs}) -> NewKind = case S4SC of {NK,_} -> NK; _ -> Kind end, case check_cm2(NewKind,S4SC,ChainCM,S) of {ChainCMRest,#xsd_state{errors=Errs}} -> check_chain(Kind,S4SCs,ChainCMRest,S); {_ChainCMRest,_S2} -> case optional(S4SC) of true -> check_chain(Kind,S4SCs,ChainCM,S); _ -> {error,{[],?MODULE,{unmatched_mandatory_object,Kind,S4SC}}} end end;check_chain(Kind,[],CM,S) -> {ok,[[],CM,Kind,S]};check_chain(Kind,Rest,CM,S) -> case all_optional(Rest) of true -> {ok,[Rest,CM,Kind,S]}; %% or {ok,[[],CM,Kind,S]} _ -> {error,{[],?MODULE,{bad_match,Rest,CM}}} end.check_alternative([S4SC,CM,Kind,S]) -> check_alternative(Kind,S4SC,CM,S).check_alternative(Kind,[S4SC|S4SCs],AltCM = [_H|_T], S=#xsd_state{errors=Err}) -> NewKind = case S4SC of {NK,_} -> NK; _ -> Kind end, case check_cm2(NewKind,S4SC,AltCM,S) of {AltCMRest,#xsd_state{errors=Err}} -> {ok,[[S4SC],AltCMRest,Kind,S]}; {AltCMRest,_S2} -> check_alternative(Kind,S4SCs,AltCMRest,S) end;check_alternative(Kind,[],_AltCM,_S) -> {error,{[],?MODULE,{no_match,Kind}}}. %% occurance_loop keeps track of the right number of elements%% Third argument is a list: [S4SContent,ContentModel]%% returns {ok,Rest} where Rest is the next unmatched abstract%% structure.occurance_loop({Min,Max},_CheckFun,[_,[]|_Rest],N) when Min =< N, Max >= N -> {ok,[]};occurance_loop(Occ={Min,Max},CheckFun,Args,N) -> Nplus1 = N+1, case CheckFun(Args) of {error,{_,_,{no_match,_}}} when Min =< N, Max >= N -> {ok,Args}; Err = {error,_} -> Err; {ok,Args} -> {error,{[],?MODULE,{no_match,occurance_kind(Args)}}}; {ok,NewArgs} when Nplus1 < Max -> occurance_loop(Occ,CheckFun,NewArgs,Nplus1); Ret = {ok,_NewArgs} -> Ret end.occurance_kind([Kind,_]) -> Kind;occurance_kind([_,_,Kind,_]) -> Kind;occurance_kind(_) -> [].%% if_simple_hd(S4SCM,ConstrCM) %% when is_record(S4SCM,chain);is_record(S4SCM,alternative);is_list(S4SCM) ->%% ConstrCM;%% if_simple_hd(_,[H|_Tl]) ->%% H.%% if_simple_tl(S4SCM,_ConstrCM)%% when is_record(S4SCM,chain);is_record(S4SCM,alternative);is_list(S4SCM) ->%% [];%% if_simple_tl(_,[_|Tl]) ->%% Tl.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%count_occur({Min,Max}) ->% {decrease(Min),decrease(Max)}; {decrease(Min),Max};count_occur(Other) -> Other.decrease(I) when is_integer(I), I > 0 -> I-1;decrease(I) -> I.decrease_occurance({K,{ID,Occ}}) -> {K,{ID,count_occur(Occ)}};decrease_occurance(Other) -> Other. %% remove_whitespace(L=[T=#xmlText{}|Rest]) ->%% case is_whitespace(T) of%% true ->%% remove_whitespace(Rest);%% _ -> L%% end;%% remove_whitespace(L) ->%% L. optional(optional_text) -> true;optional({_,{0,_}}) -> true;optional({_,{_,{0,_}}}) ->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -