Return-Path: Delivered-To: apmail-xml-forrest-dev-archive@xml.apache.org Received: (qmail 74512 invoked by uid 500); 17 Mar 2003 07:39:34 -0000 Mailing-List: contact forrest-cvs-help@xml.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: forrest-dev@xml.apache.org Delivered-To: mailing list forrest-cvs@xml.apache.org Received: (qmail 74485 invoked from network); 17 Mar 2003 07:39:34 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 17 Mar 2003 07:39:34 -0000 Received: (qmail 79385 invoked by uid 1352); 17 Mar 2003 07:39:33 -0000 Date: 17 Mar 2003 07:39:33 -0000 Message-ID: <20030317073933.79384.qmail@icarus.apache.org> From: jefft@apache.org To: xml-forrest-cvs@apache.org Subject: cvs commit: xml-forrest/src/java/components/org/apache/cocoon/transformation XPathTransformer.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N jefft 2003/03/16 23:39:33 Modified: src/java/components/org/apache/cocoon/transformation XPathTransformer.java Log: Copy across xmlns namespace declarations when the DOM tree doesn't explicitly contain them. Revision Changes Path 1.5 +42 -11 xml-forrest/src/java/components/org/apache/cocoon/transformation/XPathTransformer.java Index: XPathTransformer.java =================================================================== RCS file: /home/cvs/xml-forrest/src/java/components/org/apache/cocoon/transformation/XPathTransformer.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- XPathTransformer.java 15 Mar 2003 11:02:52 -0000 1.4 +++ XPathTransformer.java 17 Mar 2003 07:39:33 -0000 1.5 @@ -69,6 +69,8 @@ import org.w3c.dom.DOMException; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.w3c.dom.NamedNodeMap; + import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; @@ -240,34 +242,63 @@ * replicate in doc. This is used as a template, not actually * physically copied. */ - private void addNode(Document doc, Node nodeTemplate) { + private void addNode(Document doc, final Node nodeTemplate) { // Get a stack of node's ancestors (inclusive) Stack stack = new Stack(); Node parent = nodeTemplate; - while (parent != nodeTemplate.getOwnerDocument()) { + Document oldDoc = nodeTemplate.getOwnerDocument(); + while (parent != oldDoc) { stack.push(parent); parent = parent.getParentNode(); } // Example stack: (top) [ /manual, /manual/s1, /manual/s1/@title ] (bottom) - // Now from the earliest non-root ancestor, add cloned nodes to the + // Now from the earliest (root) ancestor, add cloned nodes to the // doc. We check if a suitable ancestor node doesn't already exist in // addNode() parent = doc; while (!stack.empty()) { - Node n = (Node)stack.pop(); + Node oldNode = (Node)stack.pop(); + Node newNode = null; if (!stack.empty()) { - // Shallow copy of a parent node (in example: /manual, then /manual/s1) - n = doc.importNode(n, false); - parent = findOrCreateNode(parent, n); + // Shallow copy o a parent node (in example: /manual, then /manual/s1) + newNode = doc.importNode(oldNode, false); // Do a shallow copy + copyNamespaceDeclarations(oldNode, newNode); + parent = findOrCreateNode(parent, newNode); } else { - // Deep copy of the matched node (in example: /manual/s1/@title) - parent.appendChild(doc.importNode(n, true)); + // Deep copy of the matched node (in example: /manual/s1/@title) + newNode = doc.importNode(oldNode, true); + copyNamespaceDeclarations(oldNode, newNode); + parent.appendChild(newNode); } } } /** + * Add xmlns namespace declaration attribute to newNode, based on those from oldNode. + * It seems that a DOM object built from SAX with namespace-prefixes=false + * doesn't have xmlns attribute declarations by default, so we must + * manually add them. + * @param oldNode Original node, with namespace attributes intact + * @param newNode If an Element, this node will have an xmlns + * (or xmlns:prefix) attribute added to define the node's namespace. + */ + private void copyNamespaceDeclarations(final Node oldNode, Node newNode) { + if (newNode.getNodeType() == Document.ELEMENT_NODE) { + String prefix = oldNode.getPrefix(); + String nsURI = oldNode.getNamespaceURI(); + Element newElem = (Element)newNode; + if (nsURI != null) { + if (prefix == null || prefix.equals("")) { + if (!newElem.hasAttribute("xmlns")) newElem.setAttribute("xmlns", nsURI); + } else { + if (!newElem.hasAttribute("xmlns:"+prefix)) newElem.setAttribute("xmlns:"+prefix, nsURI); + } + } + } + } + + /** * Add newNode as a child of parent, first checking if any equivalent node * to newNode already exists as a child of parent. * @@ -301,7 +332,7 @@ * This is: they are both null, or they have the same length * and are character for character identical. */ - private boolean nodeEquality(Node n1, Node n2) { + private boolean nodeEquality(final Node n1, final Node n2) { if (n1.getNodeType() != n2.getNodeType()) { return false; }