Package client.net.sf.saxon.ce.tree.util

Source Code of client.net.sf.saxon.ce.tree.util.NamespaceIterator

package client.net.sf.saxon.ce.tree.util;

import client.net.sf.saxon.ce.event.Receiver;
import client.net.sf.saxon.ce.om.NamespaceBinding;
import client.net.sf.saxon.ce.om.NodeInfo;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.type.Type;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;

/**
* This class provides an iterator over the namespace codes representing the in-scope namespaces
* of any node. It relies on nodes to implement the method
* {@link client.net.sf.saxon.ce.om.NodeInfo#getDeclaredNamespaces(client.net.sf.saxon.ce.om.NamespaceBinding[])}.
*
* <p>The result does not include the XML namespace.</p>
*/
public class NamespaceIterator implements Iterator<NamespaceBinding> {

    private NodeInfo element;
    private int index;
    private NamespaceBinding next;
    private NamespaceBinding[] localDeclarations;
    HashSet<String> undeclaredPrefixes;

    /**
     * Factory method: create an iterator over the in-scope namespace bindings for an element
     * @param element the element (or other node) whose in-scope namespaces are required. If this
     * is not an element, the result will be an empty iterator
     * @return an iterator over the namespace bindings. A namespace binding represents
     * a prefix-uri binding; the prefix and URI can be obtained by reference to the name pool. This
     * iterator will represent all the in-scope namespaces, without duplicates, and respecting namespace
     * undeclarations. It does not include the XML namespace.
     */

    public static Iterator<NamespaceBinding> iterateNamespaces(NodeInfo element) {
        if (element.getNodeKind() == Type.ELEMENT) {
            return new NamespaceIterator(element);
        } else {
            return Collections.EMPTY_LIST.iterator();
        }
    }

    /**
     * Send all the in-scope namespaces for a node (except the XML namespace) to a specified receiver
     * @param element the element in question (the method does nothing if this is not an element)
     * @param receiver the receiver to which the namespaces are notified
     */

    public static void sendNamespaces(NodeInfo element, Receiver receiver) throws XPathException {
         if (element.getNodeKind() == Type.ELEMENT) {
            boolean foundDefault = false;
            for (Iterator<NamespaceBinding> iter = iterateNamespaces(element); iter.hasNext();) {
                NamespaceBinding nb = iter.next();
                if (nb.getPrefix().isEmpty()) {
                    foundDefault = true;
                }
                receiver.namespace(nb, 0);
            }
            if (!foundDefault) {
                // see bug 5857
                receiver.namespace(NamespaceBinding.DEFAULT_UNDECLARATION, 0);
            }
        }
    }

    private NamespaceIterator(NodeInfo element) {
        this.element = element;
        undeclaredPrefixes = new HashSet(8);
        index = 0;
        localDeclarations = element.getDeclaredNamespaces(null);
    }

    public boolean hasNext() {
        if (next == null && index != 0) {
            return false;
        }
        advance();
        return next != null;
    }

    public NamespaceBinding next() {
        return next;
    }

    private void advance() {
        while (true) {
            boolean ascend = index >= localDeclarations.length;
            NamespaceBinding nsCode = null;
            if (!ascend) {
                nsCode = localDeclarations[index++];
                ascend = nsCode == null;
            }
            if (ascend) {
                element = element.getParent();
                if (element != null && element.getNodeKind() == Type.ELEMENT) {
                    localDeclarations = element.getDeclaredNamespaces(localDeclarations);
                    index = 0;
                    continue;
                } else {
                    next = null;
                    return;
                }
            }
            String uri = nsCode.getURI();
            String prefix = nsCode.getPrefix();
            if (uri.isEmpty()) {
                // this is an undeclaration
                undeclaredPrefixes.add(prefix);
            } else {
                if (undeclaredPrefixes.add(prefix)) {
                    // it was added, so it's new, so return it
                    next = nsCode;
                    return;
                }
                // else it wasn't added, so we've already seen it
            }
        }
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}


// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.
TOP

Related Classes of client.net.sf.saxon.ce.tree.util.NamespaceIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.