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