SAX2: Namespace proposal

Ray Waldin rwaldin at
Sun Dec 19 23:32:30 GMT 1999

"Clark C. Evans" wrote:
> This looks very similar to what Ray had
> proposed a few days ago.

A quick visit back to the xml-dev archives shows that this idea was around
*long* before I ever had it!  :)

John Cowan (cowan at Tue, 11 Aug 1998 14:12:38 -0400:
>> 1. A new optional application-side interface to allow applications to
>> intercept, record, and decode namespace scope events:
>>public interface NamespaceHandler {
>>public void startNamespaceScope (String prefix, String URI,
>>NamespaceResolver resolver);
>>public void endNamespaceScope (String prefix);

> In this case, perhaps leave startElement alone:
>   void startElement(String name, AttributeList atts);

Yes, this seems to be what James' proposal gives us with the  
NamespaceDeclarationsAsAttributes level, with the difference that there will be
an extra namespaceUri param to some methods which should always be null, and the
AttributeList parameter to startElement will contain namespace declarations as
well as normal attributes.  Minor inconveniences, really.

Here's a helper class to record namespace uri to prefix mappings, query those
mappings, and split qnames.  

import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Stack;
import java.util.EmptyStackException;

public class NamespacePrefixMap {
    private Hashtable prefixStacks;

    /** constructs a new NamespacePrefixMap and initializes it with the
        built-in mapping of the prefix "xml" according to REC-xml-names */
    public NamespacePrefixMap()
        prefixStacks = new Hashtable();
        add("xml", "");

    /** adds a new prefix to namespace uri mapping */
    public void add(String prefix, String nsUri) {
        Stack prefixStack;
        if((prefixStack = (Stack) prefixStacks.get(prefix)) == null) {
            // create a prefixStack for first use of each prefix
            prefixStack = new Stack();
            prefixStacks.put(prefix, prefixStack);

    /** removes a prefix to namespace uri mapping */
    public void remove(String prefix) {
        Stack prefixStack;
        if((prefixStack = (Stack) prefixStacks.get(prefix)) != null)

    /** returns the namespace uri currently bound to a given prefix or null
        if there is none */
    public String getNamespaceUri(String prefix) {
        Stack prefixStack;
        try {
            if((prefixStack = (Stack) prefixStacks.get(prefix)) != null) {
                String nsUri = (String) prefixStack.peek();

                // check to see if the default namespace is "undeclared"
                if(prefix.length() == 0 && nsUri.length() == 0) return null;

                return nsUri;
        } catch( EmptyStackException ese ) {}
        return null;

    /** returns some prefix currently bound to a given namespace uri or null
        if there is none */
    public String getPrefix(String nsUri) {
        String prefix;
        Stack prefixStack;

        // for each prefix
        for(Enumeration p = getPrefixes(); p.hasMoreElements(); ) {
            prefix = (String) p.nextElement();
            prefixStack = (Stack) prefixStacks.get(prefix);

            // is prefix currently bound to nsUri?
            if( == 1) return prefix;
        return null;

    /** returns an Enumeration of the prefixes currently declared */
    public Enumeration getPrefixes() {
        return prefixStacks.keys();

    /** indices into String array returned by splitQName() */
    public static final int LOCAL_NAME = 0;
    public static final int PREFIX = 1;
    public static final int NAMESPACE_URI = 2;

    /** Splits qname into {"localName", "prefix", "namespaceUri"} */
    public String[] splitQName(String qname) {
        String[] results = new String[3];
        int colon = qname.indexOf(':');
        if(colon == -1) {
            results[PREFIX] = "";
            results[LOCAL_NAME] = qname;
        } else {
            results[PREFIX] = qname.substring(0, colon);
            results[LOCAL_NAME] = qname.substring(colon + 1);
        results[NAMESPACE_URI] = getNamespaceUri(results[PREFIX]);
        return results;

    /** determines if name is a QName */
    public boolean isQName(String name) {
        return (name.indexOf(':') != -1);

    /** determines if name equals "xmlns" or begins with "xmlns:" */
    public boolean isNamespaceDeclaration(String name) {
        return (name.equals("xmlns") || name.startsWith("xmlns:"));

xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev at
Archived as: and on CD-ROM/ISBN 981-02-3594-1
To unsubscribe, mailto:majordomo at the following message;
unsubscribe xml-dev
To subscribe to the digests, mailto:majordomo at the following message;
subscribe xml-dev-digest
List coordinator, Henry Rzepa (mailto:rzepa at

More information about the Xml-dev mailing list