I have a problem with Xalan 2.7. Have a look at the following snippet:

<a:a1 xmlns:a="http://a";
      xmlns:b="http://b";
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
 <a:a2 xsi:type="b:B"/>
</a:a1>

As you can see, the value of the attribute 'xsi:type' contains a namespace prefix, which is declared in the root element.


When I read this document as a StreamSource or SAXSource and transform it with Xalan into a DOMResult, the namespaces are invalid because the namespace declaration 'xmlns:b="http://b";' is lost:

<a:a1 xmlns:a="http://a";>
  <a:a2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
        xsi:type="b:B"/>
</a:a1>


When I try to read the document as a DOMSource and try to transform it into a DOMResult, an exception occurs ('NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.').

I attached the example code and output.

Can somebody tell me if I'm doing something wrong,
or if this is a bug in Xalan?

Thanks in advance,
Christian
class javax.xml.transform.stream.StreamSource
Parsed only          : <a:a1 xmlns:a="http://a"; xmlns:b="http://b"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";><a:a2 
xsi:type="b:B"/></a:a1>
Null-Transform to DOM: <a:a1 xmlns:a="http://a";><a:a2 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:type="b:B"/></a:a1>

class javax.xml.transform.sax.SAXSource
Parsed only          : <a:a1 xmlns:a="http://a"; xmlns:b="http://b"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";><a:a2 
xsi:type="b:B"/></a:a1>
Null-Transform to DOM: <a:a1 xmlns:a="http://a";><a:a2 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:type="b:B"/></a:a1>

class javax.xml.transform.dom.DOMSource
Parsed only          : <a:a1 xmlns:a="http://a"; xmlns:b="http://b"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";><a:a2 
xsi:type="b:B"/></a:a1>
org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change 
an object in a way which is incorrect with regard to namespaces.
        at 
com.sun.org.apache.xerces.internal.dom.ElementNSImpl.setName(ElementNSImpl.java:149)
        at 
com.sun.org.apache.xerces.internal.dom.ElementNSImpl.<init>(ElementNSImpl.java:80)
        at 
com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.createElementNS(CoreDocumentImpl.java:2084)
        at org.apache.xml.utils.DOMBuilder.startElement(DOMBuilder.java:322)
        at 
org.apache.xalan.transformer.TransformerIdentityImpl.startElement(TransformerIdentityImpl.java:1072)
        at org.apache.xml.serializer.TreeWalker.startNode(TreeWalker.java:357)
        at org.apache.xml.serializer.TreeWalker.traverse(TreeWalker.java:143)
        at 
org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:389)
        at TransformerTest.transform(TransformerTest.java:71)
        at TransformerTest.main(TransformerTest.java:35)

class javax.xml.transform.stax.StAXSource
javax.xml.transform.TransformerException: Umsetzen einer Quelle des Typs 
javax.xml.transform.stax.StAXSource ist nicht möglich. 
        at 
org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:418)
        at TransformerTest.transform(TransformerTest.java:66)
        at TransformerTest.main(TransformerTest.java:35)
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.ParameterizedType;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.xml.sax.InputSource;

public class TransformerTest {

  private static final String INPUT
  = "<a:a1 xmlns:a='http://a'"
       + " xmlns:b='http://b' "
       + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>"
    + "<a:a2 xsi:type='b:B' /></a:a1>";
  
  
  
  public static void main(String[] args)  {
    Class[] sourceTypes = new Class[] { StreamSource.class, SAXSource.class, 
DOMSource.class, StAXSource.class };
    for (Class<? extends Source> c : sourceTypes) {
      try {
        transform(SourceProvider.getProviderFor(c, INPUT));
        System.out.println();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    
  }

  /**
   * @param p
   * @throws TransformerConfigurationException
   * @throws TransformerException
   * @throws Exception
   */
  private static void transform(SourceProvider<?> p) throws 
TransformerConfigurationException, TransformerException, Exception {
    StringWriter target;
    Transformer t;
    t = new 
org.apache.xalan.processor.TransformerFactoryImpl().newTransformer();
//    t = new 
com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl().newTransformer();
//    t = new net.sf.saxon.TransformerFactoryImpl().newTransformer();
    t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
//    System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
//        "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
    
    System.out.println(((ParameterizedType) p.getClass().getGenericSuperclass())
                       .getActualTypeArguments()[0]);
    
    
    /* Parse input document and print the result */
    target = new StringWriter();
    t.transform(p.newSource(), new StreamResult(target));
    System.out.println("Parsed only          : " + target.toString());

    /* Parse input document, transform it to DOM and print the result */
    DOMResult result = new DOMResult();
    t.transform(p.newSource(), result);
    DOMSource ds = new DOMSource(result.getNode());
    target = new StringWriter();
    t.transform(ds, new StreamResult(target));
    System.out.println("Null-Transform to DOM: " + target.toString());
    
    
  }
  
  private static abstract class SourceProvider<T extends Source> {
    protected final String xml;
    protected SourceProvider(String xml) { 
      this.xml = xml; 
    }
    public abstract T newSource() throws Exception;
    public static <T extends Source> SourceProvider<T> 
            getProviderFor(Class<T> typ, String xmlContent) {
      SourceProvider<?> result = null;
      if (typ != null) {
        if (typ.equals(DOMSource.class))    result = new 
DOMSourceProvider(xmlContent);
        if (typ.equals(SAXSource.class))    result = new 
SAXSourceProvider(xmlContent);
        if (typ.equals(StreamSource.class)) result = new 
StreamSourceProvider(xmlContent);
        if (typ.equals(StAXSource.class))   result = new 
StAXSourceProvider(xmlContent);
      }
      return (SourceProvider<T>) result;
    }
  }
  
  private static final class DOMSourceProvider extends 
SourceProvider<DOMSource> {
    protected DOMSourceProvider(String xml) { super(xml); }
    @Override
    public  DOMSource newSource() throws Exception {
      return new DOMSource(
          DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
              new InputSource(new StringReader(xml))));
    }
  }
  
  private static final class SAXSourceProvider extends 
SourceProvider<SAXSource> {
    protected SAXSourceProvider(String xml) { super(xml); }
    @Override
    public  SAXSource newSource() throws Exception {
      return new SAXSource(new InputSource(new StringReader(xml)));
    }
  }
  
  private static final class StreamSourceProvider extends 
SourceProvider<StreamSource> {
    protected StreamSourceProvider(String xml) { super(xml); }
    @Override
    public StreamSource newSource() throws Exception {
      return new StreamSource(new StringReader(xml));
    }
  }
  
  private static final class StAXSourceProvider extends 
SourceProvider<StAXSource> {
    protected StAXSourceProvider(String xml) { super(xml); }
    @Override
    public StAXSource newSource() throws Exception {
      return new 
StAXSource(XMLInputFactory.newInstance().createXMLStreamReader(new 
StringReader(xml)));
    }
  }
  
}

Reply via email to