/* * Created on 20.11.2003 * * (c) Stabsstelle IKT-Strategie des Bundes */ package at.gv.egovernment.moa.spss.slinterface.transformers; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.xerces.dom.DocumentImpl; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.traversal.DocumentTraversal; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.NodeIterator; import at.gv.egovernment.moa.spss.slinterface.Constants; /** * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) */ public class Utils { /** * * @param elem * @param prefixes * @param namespaces * @param names * * @pre elem is backed by a org.apache.xerces.dom.DocumentImpl. */ public static Element transformDeep(Element elem, Map prefixes, Map namespaces, Map names) { // Get node iterator for element DocumentTraversal docTraversal = (DocumentImpl) elem.getOwnerDocument(); NodeIterator elemsIt = docTraversal.createNodeIterator(elem, NodeFilter.SHOW_ELEMENT, null, true); // Make iterator immutable List elemsList = new LinkedList(); while (true) { Node currNode = elemsIt.nextNode(); if (currNode == null) break; elemsList.add(currNode); } Iterator elemsImmIt = elemsList.iterator(); Element returnValue = null; while (elemsImmIt.hasNext()) { Element currElem = (Element) elemsImmIt.next(); String nsUri = currElem.getNamespaceURI(); String localName = currElem.getLocalName(); QName qName = new QName(nsUri, localName); // Check if element is in "names" QName newQName = (QName)names.get(qName); if (newQName != null) { Element transformedElem = transformElem(currElem, newQName, prefixes); if (returnValue == null) returnValue = transformedElem; } else { String newNamespace = (String)namespaces.get(nsUri); if (newNamespace != null) { newQName = new QName(newNamespace, localName); Element transformedElem = transformElem(currElem, newQName, prefixes); if (returnValue == null) returnValue = transformedElem; } } } return returnValue; } /* ---------------------------------------------------------------------------------------------------- */ private static Element transformElem(Element currElem, QName newQName, Map prefixes) { Element newElem = currElem.getOwnerDocument().createElementNS(newQName.nsUrl_, (String) prefixes.get(newQName.nsUrl_) + ":" + newQName.localName_); currElem.getParentNode().replaceChild(newElem, currElem); // Treat attributes of currElem NamedNodeMap currAttrs = currElem.getAttributes(); ArrayList currAttrsList = new ArrayList(currAttrs.getLength()); for (int i = 0; i < currAttrs.getLength(); i++) currAttrsList.add(currAttrs.item(i)); for (int i = 0; i < currAttrsList.size(); i++) { Attr currAttr = (Attr)currAttrsList.get(i); currAttr.getOwnerElement().removeAttributeNode(currAttr); // Workaround for bad Xerces behaviour: default attributes in the xml namespace are created without // the xml prefix if (Constants.NSURI_XML_.equals(currAttr.getNamespaceURI()) && "space".equals(currAttr.getLocalName())) { newElem.setAttributeNS(Constants.NSURI_XML_, "xml:space", currAttr.getValue()); } else { newElem.setAttributeNode(currAttr); } } // Treat child nodes of currElem NodeList currChildren = currElem.getChildNodes(); ArrayList currChildrenList = new ArrayList(currChildren.getLength()); for (int i = 0; i < currChildren.getLength(); i++) currChildrenList.add(currChildren.item(i)); for (int i = 0; i < currChildrenList.size(); i++) { Node currChild = (Node)currChildrenList.get(i); currElem.removeChild(currChild); newElem.appendChild(currChild); } return newElem; } }