Hi, please find attached a patch for the DOMBuilder of the latest cvs of xalan-j 2.2.0.
It fixes the various namespace problems reported in my last email. Regards, Carsten
Index: DOMBuilder.java =================================================================== RCS file: /home/cvspublic/xml-xalan/java/src/org/apache/xml/utils/DOMBuilder.java,v retrieving revision 1.9 diff -u -r1.9 DOMBuilder.java --- DOMBuilder.java 2001/06/12 19:15:55 1.9 +++ DOMBuilder.java 2001/12/19 13:35:33 @@ -2,7 +2,7 @@ * The Apache Software License, Version 1.1 * * - * Copyright (c) 1999 The Apache Software Foundation. All rights + * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -18,7 +18,7 @@ * distribution. * * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: + * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, @@ -26,7 +26,7 @@ * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this - * software without prior written permission. For written + * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", @@ -60,6 +60,7 @@ import org.apache.xpath.res.XPATHErrorResources; import org.apache.xml.utils.NodeVector; import java.util.Stack; +import java.util.Vector; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.ContentHandler; @@ -78,6 +79,9 @@ implements ContentHandler, LexicalHandler { + /** use DOM Level 2 */ + public boolean m_useDOMLevel2; + /** Root document */ public Document m_doc; @@ -90,6 +94,9 @@ /** Vector of element nodes */ protected Stack m_elemStack = new Stack(); + /** The vector of namespaces declarations to include in the next element */ + private Vector m_undecl = new Vector(5); + /** * DOMBuilder instance constructor... it will add the DOM nodes * to the document fragment. @@ -101,6 +108,7 @@ { m_doc = doc; m_currentNode = node; + m_useDOMLevel2 = doc.getImplementation().hasFeature("XML", "2.0"); } /** @@ -114,6 +122,7 @@ { m_doc = doc; m_docFrag = docFrag; + m_useDOMLevel2 = doc.getImplementation().hasFeature("XML", "2.0"); } /** @@ -125,6 +134,7 @@ public DOMBuilder(Document doc) { m_doc = doc; + m_useDOMLevel2 = doc.getImplementation().hasFeature("XML", "2.0"); } /** @@ -287,7 +297,7 @@ * * * @param ns The namespace of the node - * @param localName The local part of the qualified name + * @param localName The local part of the qualified name * @param name The element name. * @param atts The attributes attached to the element, if any. * @see #endElement @@ -300,61 +310,75 @@ Element elem; - if ((null == ns) || (ns.length() == 0)) - elem = m_doc.createElement(name); + if (m_useDOMLevel2 == false) + { + if (ns != null && ns.length() > 0) + { + throw new org.xml.sax.SAXException("Document supports only DOM Level 1"); + } + elem = m_doc.createElement(localName); + } else + { + if (ns != null && ns.length() == 0) ns = null; elem = m_doc.createElementNS(ns, name); - + } append(elem); try { - int nAtts = atts.getLength(); - - if (0 != nAtts) - { - for (int i = 0; i < nAtts; i++) + // Process all attributes, leave out namespace attributes + for ( int x = 0; x < atts.getLength(); x++ ) { + String auri = atts.getURI( x ); + String aloc = atts.getLocalName( x ); + String araw = atts.getQName( x ); + String aval = atts.getValue( x ); + if ( araw.startsWith( "xmlns:" ) == false && araw.equals( "xmlns" ) == false ) { - - //System.out.println("type " + atts.getType(i) + " name " + atts.getLocalName(i) ); - // First handle a possible ID attribute - if (atts.getType(i).equalsIgnoreCase("ID")) - setIDAttribute(atts.getValue(i), elem); - - String attrNS = atts.getURI(i); - - if(attrNS == null) - attrNS = ""; // defensive, shouldn't have to do this. - - // System.out.println("attrNS: "+attrNS+", localName: "+atts.getQName(i) - // +", qname: "+atts.getQName(i)+", value: "+atts.getValue(i)); - // Crimson won't let us set an xmlns: attribute on the DOM. - String attrQName = atts.getQName(i); - if ((attrNS.length() == 0) /* || attrQName.startsWith("xmlns:") || attrQName.equals("xmlns") */) - elem.setAttribute(attrQName, atts.getValue(i)); + if (m_useDOMLevel2 == false) + { + if (auri != null && auri.length() > 0) + { + throw new org.xml.sax.SAXException("Document supports only DOM Level +1"); + } + elem.setAttribute(araw, aval); + } else { - - // elem.setAttributeNS(atts.getURI(i), atts.getLocalName(i), atts.getValue(i)); - elem.setAttributeNS(attrNS, attrQName, atts.getValue(i)); + if (auri != null && auri.length() == 0) auri = null; + elem.setAttributeNS(auri, araw, aval); } } + } + // Append the xmlns... attributes + if ( m_useDOMLevel2 == true && m_undecl.size() > 0 ) { + for ( int x = 0; x < m_undecl.size(); x++ ) { + String[] value = (String[])m_undecl.get(x); + String aname = "xmlns"; + if ( value[0].length() > 0 ) aname = "xmlns:" + value[0]; + elem.setAttributeNS( "http://www.w3.org/2000/xmlns/", aname, value[1] ); + } + m_undecl.clear(); } - + // append(elem); - + m_elemStack.push(elem); - + m_currentNode = elem; - + // append(elem); } + catch(org.xml.sax.SAXException sax) + { + throw sax; + } catch(java.lang.Exception de) { // de.printStackTrace(); throw new org.xml.sax.SAXException(de); } - + } /** @@ -442,12 +466,12 @@ * * @param ch Array containing the characters * @param start Index to start of characters in the array - * @param length Number of characters in the array + * @param length Number of characters in the array */ public void charactersRaw(char ch[], int start, int length) throws org.xml.sax.SAXException { - if(isOutsideDocElem() + if(isOutsideDocElem() && org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(ch, start, length)) return; // avoid DOM006 Hierarchy request error @@ -530,10 +554,10 @@ append(m_doc.createTextNode(s)); } - + /** * Tell if the current node is outside the document element. - * + * * @return true if the current node is outside the document element. */ private boolean isOutsideDocElem() @@ -626,7 +650,7 @@ */ public void cdata(char ch[], int start, int length) throws org.xml.sax.SAXException { - if(isOutsideDocElem() + if(isOutsideDocElem() && org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(ch, start, length)) return; // avoid DOM006 Hierarchy request error @@ -698,29 +722,8 @@ public void startPrefixMapping(String prefix, String uri) throws org.xml.sax.SAXException { - - /* - // Not sure if this is needed or wanted - // Also, it fails in the stree. - if((null != m_currentNode) - && (m_currentNode.getNodeType() == Node.ELEMENT_NODE)) - { - String qname; - if(((null != prefix) && (prefix.length() == 0)) - || (null == prefix)) - qname = "xmlns"; - else - qname = "xmlns:"+prefix; - - Element elem = (Element)m_currentNode; - String val = elem.getAttribute(qname); - if(val == null) - { - elem.setAttributeNS("http://www.w3.org/XML/1998/namespace", - qname, uri); - } - } - */ + // Insert this namespace in tables avoiding duplicates + m_undecl.addElement( new String[] {prefix, uri } ); } /** @@ -735,7 +738,22 @@ * @see #startPrefixMapping * @see #endElement */ - public void endPrefixMapping(String prefix) throws org.xml.sax.SAXException{} + public void endPrefixMapping(String prefix) + throws org.xml.sax.SAXException + { + int i = m_undecl.size(); + boolean found = false; + while (i > 0 && found == false) + { + i--; + String[] value = (String[])m_undecl.get(i); + if (value[0].equals(prefix) == true) + { + m_undecl.removeElementAt(i); + found = true; + } + } + } /** * Receive notification of a skipped entity.
