xmerl namespace handling
Robert Raschke
rtrlists@REDACTED
Mon Aug 3 13:04:14 CEST 2009
Hmm replying to myself, sorry 'bout that.
On Mon, Aug 3, 2009 at 11:42 AM, Robert Raschke <rtrlists@REDACTED>wrote:
> 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
>
>
I figured out that namespaces are kept as atoms in the xmlNamespace record
and the 'default' field of that record has a default value of []. So if I
change the first clause of mk_Ell_namespace/3 to read like follows, I can
get my XML validated:
mk_EII_namespace(_,#xmlNamespace{default=DefaultNS},_S) when
is_atom(DefaultNS) ->
DefaultNS;
Does anyone have a deeper understanding of the xmerl_xsd module to verify
that this would be the correct thing to do?
Thanks,
Robby
More information about the erlang-questions
mailing list