📄 xmerl_xsd.erl
字号:
true; %% sequence, all or choiceoptional({any,{_,{0,_},_}}) -> true;optional(#chain{occurance={0,_}}) -> true;optional(#alternative{occurance={0,_}}) -> true;optional(#chain{content=Content}) -> catch is_optional_content(Content);optional(#alternative{content=Content}) -> catch is_optional_content(Content);optional({all,{Content,_}}) -> catch is_optional_content(Content);optional(_) -> false.is_optional_content([H|T]) -> case optional(H) of true -> is_optional_content(T); false -> throw(false) end;is_optional_content([]) -> true.not_optional(X) -> case optional(X) of true -> false; _ -> true end.all_optional([]) -> true;all_optional(L) -> case filter(fun not_optional/1,L) of [] -> true; _ -> false end.%% allowed_content/2 returns a representation of the allowed content%% model for that objectallowed_content(element,_Parents) -> #chain{content= [{annotation,{0,1}}, #chain{content= [#alternative{content= [{simpleType,{1,1}},{complexType,{1,1}}], occurance={0,1}}, #alternative{content= [{unique,{1,1}},{key,{1,1}},{keyref,{1,1}}], occurance={0,unbounded}}] }] };allowed_content(attribute,_Parents) -> #chain{content=[{annotation,{0,1}},{simpleType,{0,1}}]};allowed_content(complexType,Parents) -> #chain{content= [{annotation,{0,1}}, #alternative{content= [set_occurance(allowed_content(simpleContent,Parents),{1,1}), set_occurance(allowed_content(complexContent,Parents),{1,1}), #chain{content= [#alternative{content= [{group,{1,1}},{all,{1,1}}, {choice,{1,1}},{sequence,{1,1}}], occurance={0,1}}, #chain{content= [#alternative{content= [{attribute,{1,1}}, {attributeGroup,{1,1}}], occurance={0,unbounded}}, {anyAttribute,{0,1}}] } ] } ] } ] };allowed_content(attributeGroup,Parents) -> case member(simpleContent,Parents) of true -> {annotation,{0,1}}; _ -> #chain{content= [{annotation,{0,1}}, #chain{content= [#alternative{content= [{attribute,{1,1}}, {attributeGroup,{1,1}}], occurance={0,unbounded}}, {anyAttribute,{0,1}}]}]} end;allowed_content(group,_Parents) -> #chain{content= [{annotation,{0,1}}, #alternative{content= [{all,{1,1}},{choice,{1,1}},{sequence,{1,1}}], occurance={0,1}}]};allowed_content(all,_Parents) -> #chain{content=[{annotation,{0,1}},{element,{0,unbounded}}]};allowed_content(SorC,_Parents) when SorC==sequence;SorC==choice -> #chain{content= [{annotation,{0,1}}, #alternative{content= [{element,{1,1}},{group,{1,1}}, {choice,{1,1}},{sequence,{1,1}}, {any,{1,1}}], occurance={0,unbounded}}]};allowed_content(E,_Parents) when E==any;E==selector;E==field;E==notation;E==include;E==import; E==anyAttribute -> {annotation,{0,1}};allowed_content(UKK,_Parents) when UKK==unique;UKK==key;UKK==keyref-> #chain{content= [{annotation,{0,1}}, #chain{content= [{selector,{1,1}},{selector,{1,unbounded}}]}]};allowed_content(annotation,_Parents) -> #alternative{content=[{appinfo,{1,1}},{documentation,{1,1}}], occurance={0,unbounded}};allowed_content(E,_Parents) when E==appinfo;E==documentation -> {any,{0,unbounded}};allowed_content(simpleType,_Parents) -> #chain{content= [{annotation,{0,1}}, #alternative{content=[{restriction,{1,1}},{list,{1,1}}, {union,{1,1}}]}]};allowed_content(restriction,Parents) -> case member(simpleType,Parents) of true -> allowed_content2(restriction,simpleType); _ -> case member(simpleContent,Parents) of true -> allowed_content2(restriction,simpleContent); _ -> allowed_content2(restriction,complexContent) end end;allowed_content(LU,_Parent) when LU==list;LU==union -> #chain{content=[{annotation,{0,1}},{simpleType,{0,1}}]};allowed_content(schema,_) -> #chain{content= [#alternative{content= [{include,{1,1}},{import,{1,1}}, {redefine,{1,1}},{annotation,{1,1}}], occurance={0,1}}, #chain{content= [#alternative{content= [#alternative{content= [{simpleType,{1,1}},{complexType,{1,1}}, {group,{1,1}},{attributeGroup,{1,1}}]}, {element,{1,1}}, {attribute,{1,1}}, {notation,{1,1}}]}, {annotation,{0,unbounded}}], occurance={0,unbounded}}]};allowed_content(redefine,_Parents) -> #alternative{content= [{annotation,{1,1}}, #alternative{content= [{simpleType,{1,1}},{complexType,{1,1}}, {group,{1,1}},{attributeGroup,{1,1}}]}], occurance={0,unbounded}};allowed_content(E,_Parents) when E==simpleContent; E==complexContent -> #chain{content= [{annotation,{0,1}}, #alternative{content= [{restriction,{1,1}},{extension,{1,1}}]}]};allowed_content(extension,Parents) -> case member(simpleContent,Parents) of true -> allowed_content2(extension,simpleContent); _ -> allowed_content2(extension,complexContent) end;allowed_content(minExclusive,_Parents) -> [];allowed_content(minInclusive,_Parents) -> [];allowed_content(maxExclusive,_Parents) -> [];allowed_content(maxInclusive,_Parents) -> [];allowed_content(totalDigits,_Parents) -> [];allowed_content(fractionDigits,_Parents) -> [];allowed_content(length,_Parents) -> [];allowed_content(minLength,_Parents) -> [];allowed_content(maxLength,_Parents) -> [];allowed_content(enumeration,_Parents) -> [];allowed_content(whiteSpace,_Parents) -> [];allowed_content(pattern,_Parents) -> []. allowed_content2(restriction,simpleType) -> #chain{content= [{annotation,{0,1}}, #chain{content= [{simpleType,{0,1}}, #alternative{content= [{minExclusive,{1,1}},{minInclusive,{1,1}}, {maxExclusive,{1,1}},{maxInclusive,{1,1}}, {totalDigits,{1,1}},{fractionDigits,{1,1}}, {length,{1,1}},{minLength,{1,1}}, {maxLength,{1,1}},{enumeration,{1,1}}, {whiteSpace,{1,1}},{pattern,{1,1}}], occurance={0,unbounded}}]}]};allowed_content2(restriction,simpleContent) -> #chain{content= [{annotation,{0,1}}, #chain{content= [{simpleType,{0,1}}, #alternative{content= [{minExclusive,{1,1}},{minInclusive,{1,1}}, {maxExclusive,{1,1}},{maxInclusive,{1,1}}, {totalDigits,{1,1}},{fractionDigits,{1,1}}, {length,{1,1}},{minLength,{1,1}}, {maxLength,{1,1}},{enumeration,{1,1}}, {whiteSpace,{1,1}},{pattern,{1,1}}], occurance={0,unbounded}}], occurance={0,1}}, #chain{content= [#alternative{content= [{attribute,{1,1}},{attributeGroup,{1,1}}], occurance={0,unbounded}}, {anyAttribute,{0,1}}]}]};allowed_content2(restriction,complexContent) -> #chain{content= [{annotation,{0,1}}, #alternative{content= [{group,{1,1}},{all,{1,1}},{choice,{1,1}}, {sequence,{1,1}}], occurance={0,1}}, #chain{content= [#alternative{content= [{attribute,{1,1}},{attributeGroup,{1,1}}], occurance={0,unbounded}}, {anyAttribute,{0,1}}]}]};allowed_content2(extension,simpleContent) -> #chain{content= [{annotation,{0,1}}, #chain{content= [#alternative{content= [{attribute,{1,1}},{attributeGroup,{1,1}}], occurance={0,unbounded}}, {anyAttribute,{0,1}}]}]};allowed_content2(extension,complexContent) -> #chain{content= [{annotation,{0,1}}, #chain{content= [#alternative{content= [{group,{1,1}},{all,{1,1}},{choice,{1,1}}, {sequence,{1,1}}], occurance={0,1}}, #chain{content= [#alternative{content= [{attribute,{1,1}}, {attributeGroup,{1,1}}], occurance={0,1}}, {anyAttribute,{0,1}}]}]}]}. set_occurance(Ch = #chain{},Occ) -> Ch#chain{occurance=Occ};set_occurance(Alt = #alternative{},Occ) -> Alt#alternative{occurance=Occ};set_occurance({Name,_},Occ) when is_atom(Name) -> {Name,Occ};set_occurance(CM,_) -> CM.process_external_schema_once(E,Namespace,S) when is_record(E,xmlElement) -> case get_attribute_value(schemaLocation,E,[]) of [] -> Err = {missing_schemalocation_attribute,E#xmlElement.name}, acc_errs(S,Err); Path -> process_external_schema_once(Path,Namespace,S) end;process_external_schema_once(SchemaLocation,Namespace,S) -> case fetch_external_schema(SchemaLocation,S) of {E=#xmlElement{},S2} -> case is_already_processed(Namespace,S2) of true -> save_namespace_definition(Namespace,S2); _ -> S3 = save_namespace_definition(Namespace,S2), traverse_ext_schema(E,S3#xsd_state{targetNamespace=Namespace}) end; {_,S2} -> S2 end.%% process_external_schema/2 returns:%% {ok,some_result()} | {error,reason()}process_external_schema(Path,S) when is_list(Path) -> case fetch_external_schema(Path,S) of {E=#xmlElement{},S2} -> traverse_ext_schema(E,S2); {_,S2} -> S2 end;process_external_schema(absent,S) -> S.fetch_external_schema(Path,S) when is_list(Path) -> FetchFun = S#xsd_state.fetch_fun, %% {ExtXSD,S2} = case FetchFun(Path,S) of {ok,{file,File},_} -> ?debug("scanning file: ~p~n",[File]), case xmerl_scan:file(File,S#xsd_state.xml_options) of {error,Reason} -> {error,acc_errs(S,{[],?MODULE,{parsing_external_schema_failed,File,Reason}})}; {EXSD,_} -> {EXSD,S#xsd_state{schema_name=File}} end; {_,{string,String},_} -> %% this is for a user defined fetch fun that returns an xml document on string format. ?debug("scanning string: ~p~n",[File]), case xmerl_scan:string(String,S#xsd_state.xml_options) of {error,Reason} -> {error,acc_errs(S,{[],?MODULE,{parsing_external_schema_failed,Path,Reason}})}; {EXSD,_} -> {EXSD,S#xsd_state{schema_name=Path}} end; {ok,[],_} -> {ok,S}; {_,Other,_} -> {error,acc_errs(S,{[],?MODULE,{fetch_fun_failed,Other}})} end;fetch_external_schema(absent,S) -> {ok,S}.%% The schema name is also important here because a schema may import%% and must include from the same namespace as the target namespace of%% the including schema.is_already_processed(NameSpace,#xsd_state{schema_name=SchemaName, checked_namespace_nodes=CNS}) ->%% case {keymember(SchemaName,2,CNS),keymember(NameSpace,3,CNS)} of%% {true,true} -> case keysearch(SchemaName,2,CNS) of {_,{_,_,NameSpace}} -> true; _ -> false end.%% save_namespace_definition(NameSpace, S=#xsd_state{targetNamespace=TNS, global_namespace_nodes=GNS, checked_namespace_nodes=CNS}) -> %% 1) Have to find a matching namespace in the global list for %% this schema, and get the associated prefix. 2) Then check %% whether a schema with this prefix - namespace combinaton %% already is checked, if so do nothing. 3a) If this namespace is %% checked but with another prefix only add the prefix - namespace %% pair to the checked namespace list. 3b) Otherwise add the %% prefix - namespace pair. {Prefix,S2} = case keysearch(TNS,1,GNS) of {value,{_,ImportedNodes}} -> case keysearch(NameSpace,2,ImportedNodes) of {value,{_P,_}} -> {_P,S};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -