[Expat-discuss] (no subject)

Karl Waclawek karl at waclawek.net
Mon Jun 30 16:10:06 EDT 2003


> I am sorry, may be I wasn't clear enough.
>
> Suppose I have an XML file containing:
>
> .
> .
> .
> <A xmlns:foo="uri://example" xmlns:gg="uri://example2">
>   <B attr="foo:ggg">
>   <C gg:attr2="...">
> .
> .
> .
>
> Expat can handle gg:attr2, but it cannot handle the value of attr.
>
> The type of the attribute 'attr' is QName. expat doesn't (and cannot) know that. I want to be able
to determine what namespace corresponds to foo. It would be great if expat had a function to do that
(e.g. const XML_Char  *XML_GetNamespace(const XML_Char *prefix)), but since it doesn't, I have to do
this manually by keeping track of all namespace aliases seen so far (including keeping track of the
current and previous default namespaces).
>
> The obvious way to do it is to use a stack (I assume expat uses a stack internally). I want to
avoid the overhead of calling 2 strdup()'s before storing a <prefix, namespace> pair on the stack.
This seems safe to do (not using strdup()), since expat must have the aliases stored somewhere,
otherwise it won't be able to expand elements or attributes of the form alias:local-name. I just
want to be sure that it's really safe, is it?

Expat uses mainly linked lists for implementing stacks. Have a look at the TAG and the BINDING
structure.
Check xmlparse.c for the switch() code around these token constants:
  XML_TOK_START_TAG_WITH_ATTS
  XML_TOK_EMPTY_ELEMENT_WITH_ATTS
  XML_TOK_END_TAG
and see how the code deals with "tagStack" and "tag->bindings" as well as these calls:
  addBinding()
  storeAtts()
  start/endElementHandler()
  start/endNamespaceDeclHandler

It's not for the faint of heart. ;-)

> Also, I want to take this one step further and avoid the overhead of having a separate stack, and
access expat's stack directly instead. Can you send me info on where can I find the code that deals
with storing/retrieiving <prefix, namespace> pairs? (I know my code will not be portable, but
efficiency is more important for me).
>
> My problem will be solved if expat had an XML_GetNamespace() function, so please consider having
it in future releases.

Don't take my word for it, but after looking at the code briefly, I think that you will need
to access the current top element of tagStack and search each TAG on the stack for a matching
tag->binding (going down the stack), returning the first one that matches your prefix
(since there may be multiple prefix mappings).

Expat relies on volunteer work, so if you find a nice way to do that, why not share it with the
community?

Karl




More information about the Expat-discuss mailing list