Make all XML namespace declarations canonical. - Java XML

Java examples for XML:Namespace

Description

Make all XML namespace declarations canonical.

Demo Code

/*/*  w w w  .  j av a2  s  .  com*/
    Open Aviation Map
    Copyright (C) 2012-2013 ??kos Mar?y

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
//package com.java2s;

import java.util.HashMap;

import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;

public class Main {
    /**
     * Make all XML namespace declarations canonical. This means that all
     * XML namespace declarations are moved up to the root element, and
     * the prefixes are given the same name.
     *
     * @param document the document to canonize.
     * @param nsCtx preferred namespace prefixes to use during canonizaiton.
     */
    public static void canonizeNS(Document document, NamespaceContext nsCtx) {
        DocumentTraversal t = (DocumentTraversal) document;

        // turn the default namespace explicit, if it is contained in the nsCtx
        NodeIterator it = t.createNodeIterator(document,
                NodeFilter.SHOW_ELEMENT, null, true);

        for (Node n = it.nextNode(); n != null; n = it.nextNode()) {
            NamedNodeMap attrs = n.getAttributes();
            for (int i = 0; i < attrs.getLength(); ++i) {
                Node a = attrs.item(i);
                if (XMLConstants.XMLNS_ATTRIBUTE.equals(a.getLocalName())) {
                    String prefix = nsCtx.getPrefix(a.getNodeValue());
                    if (prefix != null) {
                        // remove the default namespace attribute
                        ((Element) n).removeAttributeNS(
                                XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
                                XMLConstants.XMLNS_ATTRIBUTE);
                        --i;

                        // set an explicit prefix for this node, and all child
                        // nodes
                        ((Element) n)
                                .setAttributeNS(
                                        XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
                                        XMLConstants.XMLNS_ATTRIBUTE + ":"
                                                + prefix, a.getNodeValue());

                        n.setPrefix(prefix);

                        NodeIterator nit = t.createNodeIterator(n,
                                NodeFilter.SHOW_ELEMENT, null, true);
                        for (Node nn = nit.nextNode(); nn != null; nn = nit
                                .nextNode()) {

                            if (nn.getPrefix() == null) {
                                nn.setPrefix(prefix);
                            }
                        }
                    }
                }
            }
        }

        // collect the namespaces used in the document
        Map<String, String> nsMap = new HashMap<String, String>();
        Map<String, String> prefixMap = new HashMap<String, String>();

        it = t.createNodeIterator(document, NodeFilter.SHOW_ELEMENT, null,
                true);

        for (Node n = it.nextNode(); n != null; n = it.nextNode()) {
            NamedNodeMap attrs = n.getAttributes();
            for (int i = 0; i < attrs.getLength(); ++i) {
                Node a = attrs.item(i);
                if (XMLConstants.XMLNS_ATTRIBUTE.equals(a.getPrefix())
                        && !nsMap.containsKey(a.getNodeValue())) {

                    nsMap.put(a.getNodeValue(), a.getLocalName());
                }

                String prefix = nsCtx.getPrefix(a.getNodeValue());
                if (prefix != null) {
                    prefixMap.put(a.getLocalName(), prefix);
                } else {
                    prefix = nsMap.get(a.getNamespaceURI());
                    if (prefix != null && !prefix.equals(a.getLocalName())) {
                        prefixMap.put(a.getLocalName(), prefix);
                    }
                }
            }
        }

        // update the deduced namespace prefix map based on the supplied context
        for (String uri : nsMap.keySet()) {
            String prefix = nsCtx.getPrefix(uri);
            if (prefix != null) {
                nsMap.put(uri, prefix);
            }
        }

        // remove all namespace declaration attributes
        // and update the namespace prefixes
        it = t.createNodeIterator(document, NodeFilter.SHOW_ELEMENT, null,
                true);

        for (Node n = it.nextNode(); n != null; n = it.nextNode()) {
            if (n.getPrefix() != null
                    && prefixMap.containsKey(n.getPrefix())) {
                n.setPrefix(prefixMap.get(n.getPrefix()));
            }

            NamedNodeMap attrs = n.getAttributes();
            for (int i = 0; i < attrs.getLength(); ++i) {
                Node a = attrs.item(i);
                if (XMLConstants.XMLNS_ATTRIBUTE.equals(a.getPrefix())) {
                    ((Element) n).removeAttributeNS(
                            XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
                            a.getLocalName());
                    --i;
                } else if (a.getPrefix() != null
                        && prefixMap.containsKey(a.getPrefix())) {
                    a.setPrefix(prefixMap.get(a.getPrefix()));
                }
            }
        }

        // put all namespace declarations into the root element
        Element root = document.getDocumentElement();
        for (String uri : nsMap.keySet()) {
            root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
                    XMLConstants.XMLNS_ATTRIBUTE + ":" + nsMap.get(uri),
                    uri);
        }
    }
}

Related Tutorials