You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Daniel Barclay <Da...@digitalfocus.com> on 2000/06/07 19:31:30 UTC

bug?: element attr. affects child elem. in extern. entity [long]

Xalan (1.0.1) seems to have a weird bug involving processing of subelements 
in external entities.

The presence or absence of attributes on one element affects processing 
of other elements in ways that it shouldn't.

Specifically:

I have:
- a document entity that includes an external entity
- the external entity included by the document entity
  - it has a root element, either with or without an attribute, and with a 
    subelement
- a stylesheet that copies the input document to the output using the 
  identity-tranformation template example straight from 
  http://www.w3.org/TR/xslt#copying


When I use the version of the external entity whose root element has an 
attribute, the transformed output includes a copy of the subelement.

However, when I use the external entity with no attributes, the output 
is missing the subelement.


I suspect that the problem is related to using DOM input.

I used DOM input to Xalan because my external entity was in a string 
in memory.   I created a custom EntityResolver to get at the string, 
used Xerces' DOMParser to parse under control of my EntityResolver,
and used XSLTInputSource(Node) to pass the parsed document data to 
Xalan's XSLTProcessor.process(...) method.

Per the instructions for XSLTProcessFactory, I do use:

  ... = XSLTProcessorFactory.getProcessorUsingLiaisonName( 
    "org.apache.xalan.xpath.xdom.XercesLiaison" )

instead of simply:

  ... = XSLTProcessorFactory.getProcessor()

However, that was not sufficient to get Xalan to process the elements
from the external entity.  I also had to write:

  DOMParser parser = ...;
  parser.setFeature( 
      "http://apache.org/xml/features/dom/create-entity-ref-nodes", 
      false );

to get any of the external entity to show up in Xalan's output.


When the external entity finally showed up, I noticed that the subelement 
was missing.

It wasn't until I tried adding an attribute to the top element in the 
external entity that the subelement showed up in the transformed output.


Appended and attached (for non-quoted-printable and quoted-printable 
versions) is a test program showing the problem.

So...
- Might I be calling the wrong XSLTProcessoryFactory method?
- Am I trying to use some feature I didn't notice isn't implemented yet?
- Is there some other user error? 
- Or is there a nasty (rarely-triggered) bug? (in Xalan's stylesheet-
  processing code? in XercesLiaison? in Xerces DOM implementation?)


Thanks for your attention,

Daniel

----------------------------------------------------------------------
import org.apache.xalan.xslt.*;
import org.apache.xerces.parsers.*;
import org.xml.sax.*;
import org.w3c.dom.*;
import java.io.*;

/**
   Shows apparent Xalan 1.0.1 bug:  The presence or absence of an 
   attribute on an element in an external entity affects whether nested 
   elements in that external entity are processed by an identity template
   (straight from http://www.w3.org/TR/xslt#copying).

   <p>
   The output is:
   <pre>

   with: (note presence of '<sub2/>' )
   <?xml version="1.0" encoding="UTF-8"?>
   <test><extEnt attr="x"><sub2/></extEnt></test>
   
   without: (note absence of '<sub2/>' )
   <?xml version="1.0" encoding="UTF-8"?>
   <test><extEnt/></test>

   </pre>

   <p>
   This is with Xalan 1.0.1, Xerces 1.0.3, Sun JDK 1.2.2-001 on Windows NT.
 */
public class XalanIdentityProblem
{

    /**
       A stylesheet to copy the input to the output.
       <p>
       Note that the template is the example identity template straight 
       from http://www.w3.org/TR/xslt#copying.
     */
    static String styleSheet = 
            ""
            + "<xsl:stylesheet \n"
            + "  version=\"1.0\" \n"
            + "  xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" \n"
            + "  > \n"
            + " \n"
            + " <xsl:template match=\"@*|node()\"> \n"
            + "   <xsl:copy> \n"
            + "    <xsl:apply-templates select=\"@*|node()\"/> \n"
            + "   </xsl:copy> \n"
            + " </xsl:template> \n"
            + " \n"
            + "</xsl:stylesheet> \n"
            ;

    /**
       A document entity to include the external entity.
     */
    static String documentEntity = 
            "" 
            + "<?xml version=\"1.0\"?> \n"
            + "<!DOCTYPE test [ \n"
            + "<!ENTITY extEnt SYSTEM \"extEnt\"> \n"
            + "]> \n"
            + " \n"
            + "<test>&extEnt;</test> \n"
            ;

    /**
       An external with an attribute.
     */
    static String externalEntityWithAttribute = 
            "<extEnt attr=\"x\"><sub2></sub2></extEnt>";

    /**
       An external without the attribute.
     */
    static String externalEntityWithoutAttribute = 
            "<extEnt><sub2></sub2></extEnt>";



    public static void run( final String externalEntity )
        throws IOException,     
               SAXException
    {

        DOMParser parser = new DOMParser();
        parser.setEntityResolver(
            new EntityResolver()
                {
                    public InputSource resolveEntity( 
                        String publicId,
                        String systemId 
                        )
                    {
                        return 
                            new InputSource( 
                                new StringReader( externalEntity ) );
                    } // resolveEntity( ... )
                }
            );

        InputSource documentEntitySource = 
            new InputSource( new StringReader( documentEntity ) );

        // Note: Without the following setFeature call, none of the external 
        // entity shows up in the transformed output, implying that 
        // XSLTProcessorFactory.getProcessorUsingLiaisonName(
        // "org.apache.xalan.xpath.xdom.XercesLiaison" ) isn't working right

        parser.setFeature( 
            "http://apache.org/xml/features/dom/create-entity-ref-nodes", 
            false );

        parser.parse( documentEntitySource );

        Document document = parser.getDocument();




        XSLTProcessorFactory.
            getProcessorUsingLiaisonName( 
                "org.apache.xalan.xpath.xdom.XercesLiaison"
                );


        XSLTProcessor proc = 
            XSLTProcessorFactory.getProcessorUsingLiaisonName(
                "org.apache.xalan.xpath.xdom.XercesLiaison"
                );
        
        XSLTInputSource documentSource = 
            new XSLTInputSource( document );
        XSLTInputSource styleSource = 
            new XSLTInputSource( new StringReader( styleSheet ) );
        XSLTResultTarget target =
            new XSLTResultTarget( System.err );

        proc.process( documentSource, styleSource, target );


    } // run(...)



    public static void main( String[] args )
        throws IOException,     
               SAXException
    {
        System.err.println( "with: (note presence of '<sub2/>' )" );
        run( externalEntityWithAttribute );
        System.err.println();

        System.err.println();

        System.err.println( "without: (note absence of '<sub2/>' )" );
        run( externalEntityWithoutAttribute );
        System.err.println();

    } // main( String[] args )

} // class XalanIdentityProblem
----------------------------------------------------------------------

-- 
Daniel Barclay
Digital Focus
Daniel.Barclay@digitalfocus.com