xmerl namespace handling
Robert Raschke
rtrlists@REDACTED
Mon Aug 3 12:42:06 CEST 2009
Hi,
in xmerl_xsd.erl there's code that checks namespaces while validating where
it looks like the comments and the code disagree (in R13B01, lines
4809-4843):
%% mk_EII_QName/2
%% makes a name with qualified info out of an Element Information Item
%% A) If name is qualified get namespace matching prefix.
%% B) If not qualified search parents for a namespace:
%% 1) use default namespace if defined, else.
%% 2) if a parent is qualified use that namespace or
%% 3) no namespace is applied
mk_EII_QName(Name,#xmlElement{name=Me,namespace=NS,parents=P},S)
when is_list(Name) ->
mk_EII_QName(list_to_atom(Name),
#xmlElement{name=Me,namespace=NS,parents=P},S);
mk_EII_QName(Name,#xmlElement{name=Me,namespace=NS,parents=P},S) ->
Scope = S#xsd_state.scope,
NameStr = atom_to_list(Name),
case string:tokens(NameStr,":") of
["xmlns",PrefixDef] -> %% special case
{'xmlns',Scope,namespace(PrefixDef,NS,[])};
[Prefix,LocalName] -> %% A
{list_to_atom(LocalName),Scope,namespace(Prefix,NS,[])};
[_LocalName] -> %% B
{Name,Scope,mk_EII_namespace([{Me,0}|P],NS,S)}
end.
mk_EII_namespace([],#xmlNamespace{default=DefaultNS},_S) ->
DefaultNS;
%%mk_EII_namespace([{PName,_}|GrandPs],NS=#xmlNamespace{default=[]},S) ->
mk_EII_namespace([{PName,_}|GrandPs],NS,S) ->
NameStr = atom_to_list(PName),
case string:tokens(NameStr,":") of
[Prefix,_LocalName] ->
namespace(Prefix,NS,[]);
[_LocalName] ->
mk_EII_namespace(GrandPs,NS,S)
end;
mk_EII_namespace(_,NS,_S) ->
NS#xmlNamespace.default.
In the case B (unqualified name), it looks like the code will apply a
parent's qualified namespace, even if the node with the unqualified name has
a default namespace defined (contradicting B.1).
The upshot of this is that it is not possible to use xmerl_xsd:validate/2 to
validate unqualified internal elements that are part of a larger (qualified)
tree. The commented out line suggests to me that there was an attempt to
rectify this, but I'm not sure.
I don't really know if this is a bug or not. It looks intentional.
Myself, I would think that mk_Ell_namespace/3 should have a first clause
along the lines of
mk_EII_namespace(_,#xmlNamespace{default=DefaultNS},_S) when
is_list(DefaultNS), length(DefaultNS)>0 ->
DefaultNS;
to agree with the comment.
But is the comment correct in terms of XML/XSD/namespace handling?
Robby
More information about the erlang-questions
mailing list