You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by zo...@apache.org on 2004/02/24 04:55:48 UTC

cvs commit: xml-xalan/java/src/org/apache/xml/utils XMLChar.java

zongaro     2004/02/23 19:55:48

  Modified:    java/src/org/apache/xalan/templates ElemAttribute.java
                        ElemElement.java ElemPI.java
                        ElemTemplateElement.java
               java/src/org/apache/xalan/xsltc/compiler ApplyTemplates.java
                        AttributeSet.java Copy.java DecimalFormatting.java
                        Key.java LiteralElement.java Output.java
                        ProcessingInstruction.java Template.java
                        XslAttribute.java XslElement.java
               java/src/org/apache/xalan/xsltc/compiler/util
                        ErrorMessages.java ErrorMsg.java Util.java
               java/src/org/apache/xalan/xsltc/runtime BasisLibrary.java
                        ErrorMessages.java
               java/src/org/apache/xml/utils XMLChar.java
  Log:
  Patch for Bugzilla bug report 24988 from Joanne Tong (joannet () ca ! ibm ! com)
  reviewed by myself.
  
  Changes required to test whether an attribute value that is required to be
  a QName, NCName or whitespace-separated list of QNames actually meets that
  requirement.
  
  Revision  Changes    Path
  1.27      +3 -2      xml-xalan/java/src/org/apache/xalan/templates/ElemAttribute.java
  
  Index: ElemAttribute.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemAttribute.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- ElemAttribute.java	16 Feb 2004 20:32:32 -0000	1.26
  +++ ElemAttribute.java	24 Feb 2004 03:55:47 -0000	1.27
  @@ -25,6 +25,7 @@
   import org.apache.xml.serializer.NamespaceMappings;
   import org.apache.xml.serializer.SerializationHandler;
   import org.apache.xml.utils.QName;
  +import org.apache.xml.utils.XMLChar;
   
   import org.xml.sax.SAXException;
   
  @@ -156,7 +157,7 @@
           return false;
         if(nodeName.equals("xmlns"))
           return false;
  -      return super.validateNodeName(nodeName);
  +      return XMLChar.isValidQName(nodeName);
      }
     
     /**
  
  
  
  1.36      +3 -41     xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java
  
  Index: ElemElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- ElemElement.java	16 Feb 2004 20:32:32 -0000	1.35
  +++ ElemElement.java	24 Feb 2004 03:55:47 -0000	1.36
  @@ -24,6 +24,7 @@
   import org.apache.xalan.transformer.TransformerImpl;
   import org.apache.xml.serializer.SerializationHandler;
   import org.apache.xml.utils.QName;
  +import org.apache.xml.utils.XMLChar;
   import org.apache.xpath.XPathContext;
   import org.xml.sax.SAXException;
   
  @@ -154,45 +155,6 @@
     {
       return Constants.ELEMNAME_ELEMENT_STRING;
     }
  -  
  -  /**
  -   * Validate that the node name is good.
  -   * 
  -   * @param nodeName Name of the node being constructed, which may be null.
  -   * 
  -   * @return true if the node name is valid, false otherwise.
  -   */
  -   protected boolean validateNodeName(String nodeName)
  -   {
  -    if(nodeName == null)
  -      return false;
  -
  -    int len = nodeName.length();
  -    
  -    if(len == 0)
  -      return false;
  -      
  -    int indexOfNSSep = nodeName.indexOf(':');
  -
  -    if(indexOfNSSep + 1 == len)
  -      return false;
  -      
  -    if(indexOfNSSep == 0)
  -      return false;
  -      
  -    String localName = QName.getLocalPart(nodeName);
  -      
  -    if(isValidNCName(localName))
  -    {
  -      String prefix = QName.getPrefixPart(nodeName);
  -      if(prefix.length() == 0)
  -        return true;
  -      if(isValidNCName(prefix))
  -        return true;
  -    }
  -
  -    return false;
  -   }
      
     /**
      * Resolve the namespace into a prefix.  Meant to be
  @@ -251,7 +213,7 @@
       String nodeNamespace = "";
   
       // Only validate if an AVT was used.
  -    if ((nodeName != null) && (!m_name_avt.isSimple()) && (!validateNodeName(nodeName)))
  +    if ((nodeName != null) && (!m_name_avt.isSimple()) && (!XMLChar.isValidQName(nodeName)))
       {
         transformer.getMsgMgr().warn(
           this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
  
  
  
  1.19      +3 -2      xml-xalan/java/src/org/apache/xalan/templates/ElemPI.java
  
  Index: ElemPI.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemPI.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- ElemPI.java	16 Feb 2004 20:32:32 -0000	1.18
  +++ ElemPI.java	24 Feb 2004 03:55:47 -0000	1.19
  @@ -22,6 +22,7 @@
   
   import org.apache.xalan.res.XSLTErrorResources;
   import org.apache.xalan.transformer.TransformerImpl;
  +import org.apache.xml.utils.XMLChar;
   import org.apache.xpath.XPathContext;
   
   /**
  @@ -145,7 +146,7 @@
       
       // Only check if an avt was used (ie. this wasn't checked at compose time.)
       // Ignore processing instruction, if invalid
  -    else if ((!m_name_atv.isSimple()) && (!isValidNCName(piName)))
  +    else if ((!m_name_atv.isSimple()) && (!XMLChar.isValidNCName(piName)))
       {
        	transformer.getMsgMgr().warn(
           this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME,
  
  
  
  1.65      +1 -32     xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java
  
  Index: ElemTemplateElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java,v
  retrieving revision 1.64
  retrieving revision 1.65
  diff -u -r1.64 -r1.65
  --- ElemTemplateElement.java	16 Feb 2004 20:32:32 -0000	1.64
  +++ ElemTemplateElement.java	24 Feb 2004 03:55:47 -0000	1.65
  @@ -214,37 +214,6 @@
     }
   
     /**
  -   * Validate that the string is an NCName.
  -   *
  -   * @param s The name in question.
  -   * @return True if the string is a valid NCName according to XML rules.
  -   * @see <a href="http://www.w3.org/TR/REC-xml-names#NT-NCName">XXX in XSLT Specification</a>
  -   */
  -  protected boolean isValidNCName(String s)
  -  {
  -
  -    int len = s.length();
  -    char c = s.charAt(0);
  -
  -    if (!(Character.isLetter(c) || (c == '_')))
  -      return false;
  -
  -    if (len > 0)
  -    {
  -      for (int i = 1; i < len; i++)
  -      {
  -        c = s.charAt(i);
  -
  -        if (!(Character.isLetterOrDigit(c) || (c == '_') || (c == '-')
  -              || (c == '.')))
  -          return false;
  -      }
  -    }
  -
  -    return true;
  -  }
  -
  -  /**
      * Throw a template element runtime error.  (Note: should we throw a TransformerException instead?)
      *
      * @param msg key of the error that occured.
  
  
  
  1.21      +6 -1      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
  
  Index: ApplyTemplates.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- ApplyTemplates.java	16 Feb 2004 22:24:28 -0000	1.20
  +++ ApplyTemplates.java	24 Feb 2004 03:55:47 -0000	1.21
  @@ -36,6 +36,7 @@
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
   import org.apache.xalan.xsltc.compiler.util.Util;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Jacek Ambroziak
  @@ -72,6 +73,10 @@
   	}
   	
   	if (mode.length() > 0) {
  +            if (!XMLChar.isValidQName(mode)) {
  +                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, mode, this);
  +                parser.reportError(Constants.ERROR, err);           
  +            }		
   	    _modeName = parser.getQNameIgnoreDefaultNs(mode);
   	}
   	
  
  
  
  1.17      +14 -2     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java
  
  Index: AttributeSet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- AttributeSet.java	16 Feb 2004 22:24:29 -0000	1.16
  +++ AttributeSet.java	24 Feb 2004 03:55:47 -0000	1.17
  @@ -31,6 +31,8 @@
   import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
  +import org.apache.xalan.xsltc.compiler.util.Util;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Jacek Ambroziak
  @@ -81,7 +83,13 @@
       public void parseContents(Parser parser) {
   	
   	// Get this attribute set's name
  -	_name = parser.getQNameIgnoreDefaultNs(getAttribute("name"));
  +        final String name = getAttribute("name");
  +        
  +        if (!XMLChar.isValidQName(name)) {
  +            ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
  +            parser.reportError(Constants.ERROR, err);           
  +        }        
  +        _name = parser.getQNameIgnoreDefaultNs(name);
   	if ((_name == null) || (_name.equals(EMPTYSTRING))) {
   	    ErrorMsg msg = new ErrorMsg(ErrorMsg.UNNAMED_ATTRIBSET_ERR, this);
   	    parser.reportError(Constants.ERROR, msg);
  @@ -90,6 +98,10 @@
   	// Get any included attribute sets (similar to inheritance...)
   	final String useSets = getAttribute("use-attribute-sets");
   	if (useSets.length() > 0) {
  +            if (!Util.isValidQNames(useSets)) {
  +                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this);
  +                parser.reportError(Constants.ERROR, err);	
  +            }		
   	    _useSets = new UseAttributeSets(useSets, parser);
   	}
   
  
  
  
  1.11      +6 -1      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Copy.java
  
  Index: Copy.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Copy.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- Copy.java	16 Feb 2004 22:24:28 -0000	1.10
  +++ Copy.java	24 Feb 2004 03:55:47 -0000	1.11
  @@ -33,6 +33,7 @@
   import org.apache.bcel.generic.InstructionList;
   import org.apache.bcel.generic.LocalVariableGen;
   import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
  +import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
   import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
  @@ -48,6 +49,10 @@
       public void parseContents(Parser parser) {
   	final String useSets = getAttribute("use-attribute-sets");
   	if (useSets.length() > 0) {
  +            if (!Util.isValidQNames(useSets)) {
  +                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this);
  +                parser.reportError(Constants.ERROR, err);	
  +            }		
   	    _useSets = new UseAttributeSets(useSets, parser);
   	}
   	parseChildren(parser);
  
  
  
  1.14      +13 -5     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/DecimalFormatting.java
  
  Index: DecimalFormatting.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/DecimalFormatting.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- DecimalFormatting.java	16 Feb 2004 22:24:29 -0000	1.13
  +++ DecimalFormatting.java	24 Feb 2004 03:55:47 -0000	1.14
  @@ -31,6 +31,7 @@
   import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Jacek Ambroziak
  @@ -56,10 +57,17 @@
        */
       public void parseContents(Parser parser) {
   	// Get the name of these decimal formatting symbols
  -	_name = parser.getQNameIgnoreDefaultNs(getAttribute("name"));
  -	if (_name == null) {
  -	    _name = parser.getQNameIgnoreDefaultNs(EMPTYSTRING);
  -	}
  +        final String name = getAttribute("name");
  +        if (name.length() > 0) {
  +            if (!XMLChar.isValidQName(name)){
  +                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
  +                parser.reportError(Constants.ERROR, err);           
  +            }
  +        }
  +        _name = parser.getQNameIgnoreDefaultNs(name);
  +        if (_name == null) {
  +            _name = parser.getQNameIgnoreDefaultNs(EMPTYSTRING);
  +        }         
   
   	// Check if a set of symbols has already been registered under this name
   	SymbolTable stable = parser.getSymbolTable();
  
  
  
  1.18      +8 -2      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Key.java
  
  Index: Key.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Key.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Key.java	16 Feb 2004 22:24:28 -0000	1.17
  +++ Key.java	24 Feb 2004 03:55:47 -0000	1.18
  @@ -42,6 +42,7 @@
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
   import org.apache.xalan.xsltc.compiler.util.Util;
   import org.apache.xalan.xsltc.dom.Axis;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Morten Jorgensen
  @@ -76,7 +77,12 @@
       public void parseContents(Parser parser) {
   
   	// Get the required attributes and parser XPath expressions
  -	_name = parser.getQNameIgnoreDefaultNs(getAttribute("name"));
  +        final String name = getAttribute("name");
  +        if (!XMLChar.isValidQName(name)){
  +            ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
  +            parser.reportError(Constants.ERROR, err);           
  +        }
  +        _name = parser.getQNameIgnoreDefaultNs(name);
   	_match = parser.parsePattern(this, "match", null);
   	_use = parser.parseExpression(this, "use", null);
   
  
  
  
  1.25      +6 -1      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
  
  Index: LiteralElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LiteralElement.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- LiteralElement.java	16 Feb 2004 22:24:28 -0000	1.24
  +++ LiteralElement.java	24 Feb 2004 03:55:47 -0000	1.25
  @@ -27,6 +27,7 @@
   import org.apache.bcel.generic.InstructionList;
   import org.apache.bcel.generic.PUSH;
   import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
  +import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
   import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
  @@ -250,6 +251,10 @@
   	    // in the vector or attributes to make sure that later local
   	    // attributes can override an attributes in the set.
   	    if (qname == parser.getUseAttributeSets()) {
  +            	if (!Util.isValidQNames(val)) {
  +                    ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, val, this);
  +                    parser.reportError(Constants.ERROR, err);	
  +               }
   		setFirstAttribute(new UseAttributeSets(val, parser));
   	    }
   	    // Handle xsl:extension-element-prefixes
  
  
  
  1.25      +18 -5     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Output.java
  
  Index: Output.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Output.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Output.java	16 Feb 2004 22:24:29 -0000	1.24
  +++ Output.java	24 Feb 2004 03:55:48 -0000	1.25
  @@ -35,6 +35,7 @@
   import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
   import org.apache.xalan.xsltc.compiler.util.Util;
   import org.apache.xml.serializer.Encodings;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Jacek Ambroziak
  @@ -123,14 +124,21 @@
   	    outputProperties.setProperty(OutputKeys.VERSION, _version);
   	}
   
  -	// Get the output method - "xml", "html", "text" or <qname>
  +	// Get the output method - "xml", "html", "text" or <qname> (but not ncname)
   	_method = getAttribute("method");
   	if (_method.equals(Constants.EMPTYSTRING)) {
   	    _method = null;
   	}
   	if (_method != null) {
  -	    _method = _method.toLowerCase();
  -	    outputProperties.setProperty(OutputKeys.METHOD, _method);
  +            _method = _method.toLowerCase();
  +            if ((_method.equals("xml"))||
  +                (_method.equals("html"))||
  +                (_method.equals("text"))||
  +                ((XMLChar.isValidQName(_method)&&(_method.indexOf(":") > 0)))) {
  +	       outputProperties.setProperty(OutputKeys.METHOD, _method);
  +            } else {
  +                reportError(this, parser, ErrorMsg.INVALID_METHOD_IN_OUTPUT, _method);
  +            }
   	}
   
   	// Get the output encoding - any value accepted here
  @@ -201,8 +209,13 @@
   
   	    // Make sure to store names in expanded form
   	    while (tokens.hasMoreTokens()) {
  +            	String qname = tokens.nextToken();
  +                if (!XMLChar.isValidQName(qname)) {
  +                    ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, qname, this);
  +                    parser.reportError(Constants.ERROR, err);	
  +                }	    	
   		expandedNames.append(
  -		   parser.getQName(tokens.nextToken()).toString()).append(' ');
  +        	   parser.getQName(qname).toString()).append(' ');
   	    }
   	    _cdata = expandedNames.toString();
   	    if (_cdataToMerge != null) {
  
  
  
  1.11      +57 -10    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ProcessingInstruction.java
  
  Index: ProcessingInstruction.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ProcessingInstruction.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ProcessingInstruction.java	16 Feb 2004 22:24:28 -0000	1.10
  +++ ProcessingInstruction.java	24 Feb 2004 03:55:48 -0000	1.11
  @@ -19,16 +19,22 @@
   
   package org.apache.xalan.xsltc.compiler;
   
  +import org.apache.bcel.generic.ALOAD;
  +import org.apache.bcel.generic.ASTORE;
   import org.apache.bcel.generic.ConstantPoolGen;
   import org.apache.bcel.generic.GETFIELD;
   import org.apache.bcel.generic.INVOKEINTERFACE;
  +import org.apache.bcel.generic.INVOKESTATIC;
   import org.apache.bcel.generic.INVOKEVIRTUAL;
   import org.apache.bcel.generic.InstructionList;
  +import org.apache.bcel.generic.LocalVariableGen;
   import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
   import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
   import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
  +import org.apache.xalan.xsltc.compiler.util.Util;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Jacek Ambroziak
  @@ -37,10 +43,24 @@
   final class ProcessingInstruction extends Instruction {
   
       private AttributeValue _name; // name treated as AVT (7.1.3)
  +    private boolean _isLiteral = false;  // specified name is not AVT  
       
       public void parseContents(Parser parser) {
   	final String name  = getAttribute("name");
  -	_name = AttributeValue.create(this, name, parser);
  +    
  +        if (name.length() > 0) {
  +            _isLiteral = Util.isLiteral(name);
  +            if (_isLiteral) {
  +                if (!XMLChar.isValidNCName(name)) {
  +                    ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_NCNAME_ERR, name, this);
  +                    parser.reportError(Constants.ERROR, err);           
  +                }
  +            }   
  +            _name = AttributeValue.create(this, name, parser);
  +        }
  +        else
  +            reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name");
  +            
   	if (name.equals("xml")) {
   	    reportError(this, parser, ErrorMsg.ILLEGAL_PI_ERR, "xml");
   	}
  @@ -56,14 +76,41 @@
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
   	final ConstantPoolGen cpg = classGen.getConstantPool();
   	final InstructionList il = methodGen.getInstructionList();
  -
  -	// Save the current handler base on the stack
  -	il.append(methodGen.loadHandler());
  -	il.append(DUP);		// first arg to "attributes" call
  -	
  -	// push attribute name
  -	_name.translate(classGen, methodGen);// 2nd arg
  -
  +    
  +        if (!_isLiteral) {
  +            // if the ncname is an AVT, then the ncname has to be checked at runtime if it is a valid ncname
  +            LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue",
  +            Util.getJCRefType(STRING_SIG),
  +            il.getEnd());
  +            
  +            // store the name into a variable first so _name.translate only needs to be called once  
  +            _name.translate(classGen, methodGen);
  +            il.append(new ASTORE(nameValue.getIndex()));
  +            il.append(new ALOAD(nameValue.getIndex()));
  +            
  +            // call checkNCName if the name is an AVT
  +            final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkNCName",
  +                                "("
  +                                +STRING_SIG
  +                                +")V");                 
  +                                il.append(new INVOKESTATIC(check));
  +            
  +            // Save the current handler base on the stack
  +            il.append(methodGen.loadHandler());
  +            il.append(DUP);     // first arg to "attributes" call            
  +            
  +            // load name value again    
  +            il.append(new ALOAD(nameValue.getIndex()));            
  +        } else {    
  +            // Save the current handler base on the stack
  +            il.append(methodGen.loadHandler());
  +            il.append(DUP);     // first arg to "attributes" call
  +            
  +            // Push attribute name
  +            _name.translate(classGen, methodGen);// 2nd arg
  +        
  +        }
  +        
   	il.append(classGen.loadTranslet());
   	il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
   					       "stringValueHandler",
  
  
  
  1.25      +11 -1     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Template.java
  
  Index: Template.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Template.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Template.java	16 Feb 2004 22:25:10 -0000	1.24
  +++ Template.java	24 Feb 2004 03:55:48 -0000	1.25
  @@ -32,6 +32,8 @@
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
   import org.apache.xalan.xsltc.compiler.util.Util;
  +import org.apache.xml.utils.XMLChar;
  +
   
   /**
    * @author Jacek Ambroziak
  @@ -192,10 +194,18 @@
   	_stylesheet = super.getStylesheet();
   
   	if (name.length() > 0) {
  +            if (!XMLChar.isValidQName(name)) {
  +                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
  +                parser.reportError(Constants.ERROR, err);           
  +            }                
   	    _name = parser.getQNameIgnoreDefaultNs(name);
   	}
   	
   	if (mode.length() > 0) {
  +            if (!XMLChar.isValidQName(mode)) {
  +                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, mode, this);
  +                parser.reportError(Constants.ERROR, err);           
  +            } 		
   	    _mode = parser.getQNameIgnoreDefaultNs(mode);
   	}
   	
  
  
  
  1.24      +55 -15    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslAttribute.java
  
  Index: XslAttribute.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslAttribute.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- XslAttribute.java	16 Feb 2004 22:25:33 -0000	1.23
  +++ XslAttribute.java	24 Feb 2004 03:55:48 -0000	1.24
  @@ -21,10 +21,14 @@
   
   import java.util.Vector;
   
  +import org.apache.bcel.generic.ALOAD;
  +import org.apache.bcel.generic.ASTORE;
   import org.apache.bcel.generic.ConstantPoolGen;
   import org.apache.bcel.generic.GETFIELD;
  +import org.apache.bcel.generic.INVOKESTATIC;
   import org.apache.bcel.generic.INVOKEVIRTUAL;
   import org.apache.bcel.generic.InstructionList;
  +import org.apache.bcel.generic.LocalVariableGen;
   import org.apache.bcel.generic.PUSH;
   import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
   import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
  @@ -32,6 +36,7 @@
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
   import org.apache.xalan.xsltc.compiler.util.Util;
  +import org.apache.xml.utils.XMLChar;
   
   import org.apache.xml.serializer.ElemDesc;
   import org.apache.xml.serializer.SerializationHandler;
  @@ -49,6 +54,7 @@
       private AttributeValue _name; 	// name treated as AVT (7.1.3)
       private AttributeValueTemplate _namespace = null;
       private boolean _ignore = false;
  +    private boolean _isLiteral = false;  // specified name is not AVT  
   
       /**
        * Returns the name of the attribute
  @@ -78,10 +84,18 @@
   	QName qname = parser.getQName(name, false);
   	final String prefix = qname.getPrefix();
   
  -	if ((prefix != null) && (prefix.equals(XMLNS_PREFIX))) {
  +        if (((prefix != null) && (prefix.equals(XMLNS_PREFIX)))||(name.equals(XMLNS_PREFIX))) {
   	    reportError(this, parser, ErrorMsg.ILLEGAL_ATTR_NAME_ERR, name);
   	    return;
   	}
  +  
  +        _isLiteral = Util.isLiteral(name);
  +        if (_isLiteral) {
  +            if (!XMLChar.isValidQName(name)) {
  +                reportError(this, parser, ErrorMsg.ILLEGAL_ATTR_NAME_ERR, name);
  +                return;
  +            }
  +        }
   
   	// Ignore attribute if preceeded by some other type of element
   	final SyntaxTreeNode parent = getParent();
  @@ -151,11 +165,6 @@
   	    }
   	}
   
  -	if (name.equals(XMLNS_PREFIX)) {
  -	    reportError(this, parser, ErrorMsg.ILLEGAL_ATTR_NAME_ERR, name);
  -	    return;
  -	}
  -
   	if (parent instanceof LiteralElement) {
   	    ((LiteralElement)parent).addAttribute(this);
   	}
  @@ -183,7 +192,7 @@
   	final InstructionList il = methodGen.getInstructionList();
   
   	if (_ignore) return;
  -	_ignore = true;
  +	_ignore = true;    
   
   	// Compile code that emits any needed namespace declaration
   	if (_namespace != null) {
  @@ -193,13 +202,40 @@
   	    _namespace.translate(classGen,methodGen);
   	    il.append(methodGen.namespace());
   	}
  -
  -	// Save the current handler base on the stack
  -	il.append(methodGen.loadHandler());
  -	il.append(DUP);		// first arg to "attributes" call
  -	
  -	// Push attribute name
  -	_name.translate(classGen, methodGen);// 2nd arg
  +    
  +        if (!_isLiteral) {
  +            // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname
  +            LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue",
  +                    Util.getJCRefType(STRING_SIG),
  +                    il.getEnd());
  +                    
  +            // store the name into a variable first so _name.translate only needs to be called once  
  +            _name.translate(classGen, methodGen);
  +            il.append(new ASTORE(nameValue.getIndex()));
  +            il.append(new ALOAD(nameValue.getIndex()));
  +            
  +            // call checkQName if the name is an AVT
  +            final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkAttribQName",
  +                            "("
  +                            +STRING_SIG
  +                            +")V");                 
  +            il.append(new INVOKESTATIC(check));
  +            
  +            // Save the current handler base on the stack
  +            il.append(methodGen.loadHandler());
  +            il.append(DUP);     // first arg to "attributes" call            
  +            
  +            // load name value again    
  +            il.append(new ALOAD(nameValue.getIndex()));            
  +        } else {    
  +            // Save the current handler base on the stack
  +            il.append(methodGen.loadHandler());
  +            il.append(DUP);     // first arg to "attributes" call
  +            
  +            // Push attribute name
  +            _name.translate(classGen, methodGen);// 2nd arg
  +    
  +        }
   
   	// Push attribute value - shortcut for literal strings
   	if ((elementCount() == 1) && (elementAt(0) instanceof Text)) {
  @@ -243,8 +279,12 @@
   	    // call "attribute"
   	    il.append(methodGen.attribute());
   	}
  +            
   	// Restore old handler base from stack
   	il.append(methodGen.storeHandler());
  +    
  +
  +        
       }
   
   }
  
  
  
  1.23      +45 -49    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslElement.java
  
  Index: XslElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslElement.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- XslElement.java	16 Feb 2004 22:25:33 -0000	1.22
  +++ XslElement.java	24 Feb 2004 03:55:48 -0000	1.23
  @@ -19,7 +19,10 @@
   
   package org.apache.xalan.xsltc.compiler;
   
  +import org.apache.bcel.generic.ALOAD;
  +import org.apache.bcel.generic.ASTORE;
   import org.apache.bcel.generic.ConstantPoolGen;
  +import org.apache.bcel.generic.ICONST;
   import org.apache.bcel.generic.INVOKESTATIC;
   import org.apache.bcel.generic.InstructionList;
   import org.apache.bcel.generic.LocalVariableGen;
  @@ -30,6 +33,7 @@
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
   import org.apache.xalan.xsltc.compiler.util.Util;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Jacek Ambroziak
  @@ -61,39 +65,6 @@
   	return false;
       }
   
  -    /**
  -     * Checks if <param>str</param> is a literal (i.e. not an AVT) or not.
  -     */
  -    private boolean isLiteral(String str) {
  -	final int length = str.length();
  -	for (int i = 0; i < length; i++) {
  -	    if (str.charAt(i) == '{' && str.charAt(i + 1) != '{') {
  -		return false;
  -	    }
  -	}
  -	return true;
  -    }
  -
  -    /**
  -     * Simple check to determine if qname is legal. If it returns false
  -     * then <param>str</param> is illegal; if it returns true then 
  -     * <param>str</param> may or may not be legal.
  -     */
  -    private boolean isLegalName(String str) {
  -	if (str.indexOf(' ') > -1) {
  -	    return false;
  -	}
  -	final int colon = str.indexOf(':');
  -	if (colon == 0 || colon == str.length() - 1) {
  -	    return false;
  -	}
  -	final char first = str.charAt(0);
  -	if (!Character.isLetter(first) && first != '_') {
  -	    return false;
  -	}
  -	return true;
  -    }
  -
       public void parseContents(Parser parser) {
   	final SymbolTable stable = parser.getSymbolTable();
   
  @@ -112,9 +83,9 @@
   	String namespace = getAttribute("namespace");
   
   	// Optimize compilation when name is known at compile time
  -	_isLiteralName = isLiteral(name);
  +        _isLiteralName = Util.isLiteral(name);
   	if (_isLiteralName) {
  -	    if (!isLegalName(name)) {
  +            if (!XMLChar.isValidQName(name)) {
   		ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_ELEM_NAME_ERR,
   					    name, this);
   		parser.reportError(WARNING, msg);
  @@ -146,7 +117,7 @@
   	    }
   	    else {
   		if (prefix == EMPTYSTRING) {
  -		    if (isLiteral(namespace)) {
  +        	    if (Util.isLiteral(namespace)) {
   			prefix = lookupPrefix(namespace);
   			if (prefix == null) {
   			    prefix = stable.generateNamespacePrefix();
  @@ -173,6 +144,10 @@
   
   	final String useSets = getAttribute("use-attribute-sets");
   	if (useSets.length() > 0) {
  +            if (!Util.isValidQNames(useSets)) {
  +                ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, useSets, this);
  +                parser.reportError(Constants.ERROR, err);	
  +            }
   	    setFirstElement(new UseAttributeSets(useSets, parser));
   	}
   
  @@ -243,11 +218,30 @@
   	}
   
   	if (!_ignore) {
  -	    // Push handler for call to endElement()
  -	    il.append(methodGen.loadHandler());
  -
  -	    // Push name and namespace URI
  -	    _name.translate(classGen, methodGen);
  +       
  +            // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname
  +            LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue",
  +                    Util.getJCRefType(STRING_SIG),
  +                    il.getEnd());
  +                    
  +            // store the name into a variable first so _name.translate only needs to be called once  
  +            _name.translate(classGen, methodGen);
  +            il.append(new ASTORE(nameValue.getIndex()));
  +            il.append(new ALOAD(nameValue.getIndex()));
  +            
  +            // call checkQName if the name is an AVT
  +            final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkQName",
  +                            "("
  +                            +STRING_SIG
  +                            +")V");                 
  +            il.append(new INVOKESTATIC(check));
  +            
  +            // Push handler for call to endElement()
  +            il.append(methodGen.loadHandler());         
  +            
  +            // load name value again    
  +            il.append(new ALOAD(nameValue.getIndex()));  
  +                    
   	    if (_namespace != null) {
   		_namespace.translate(classGen, methodGen);
   	    }
  @@ -259,14 +253,16 @@
   	    il.append(methodGen.loadHandler());
   	    il.append(methodGen.loadDOM());
   	    il.append(methodGen.loadCurrentNode());
  +        
  +            // Invoke BasisLibrary.startXslElemCheckQName()
  +            il.append(new INVOKESTATIC(
  +            cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement",
  +                    "(" + STRING_SIG 
  +                    + STRING_SIG 
  +                    + TRANSLET_OUTPUT_SIG 
  +                    + DOM_INTF_SIG + "I)" + STRING_SIG)));                
  +
   
  -	    // Invoke BasisLibrary.startXslElement()
  -	    il.append(new INVOKESTATIC(
  -		cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement",
  -		      "(" + STRING_SIG 
  -			  + STRING_SIG 
  -			  + TRANSLET_OUTPUT_SIG 
  -			  + DOM_INTF_SIG + "I)" + STRING_SIG)));
   	}
   
   	translateContents(classGen, methodGen);
  
  
  
  1.23      +33 -3     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java
  
  Index: ErrorMessages.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- ErrorMessages.java	16 Feb 2004 22:26:44 -0000	1.22
  +++ ErrorMessages.java	24 Feb 2004 03:55:48 -0000	1.23
  @@ -889,8 +889,38 @@
            * stylesheet (see above).
            */
           {ErrorMsg.RUNTIME_ERROR_KEY,
  -        "Translet errors:"}
  +        "Translet errors:"},
  +        
  +        /*
  +         * Note to translators:  An attribute whose value is constrained to
  +         * be a "QName" or a list of "QNames" had a value that was incorrect.
  +         * 'QName' is an XML syntactic term that must not be translated.  The
  +         * substitution text contains the actual value of the attribute.
  +         */
  +        {ErrorMsg.INVALID_QNAME_ERR,
  +        "An attribute whose value must be a QName or whitespace-separated list of QNames had the value ''{0}''"}, 
   
  +        /*
  +         * Note to translators:  An attribute whose value is required to
  +         * be an "NCName".
  +         * 'NCName' is an XML syntactic term that must not be translated.  The
  +         * substitution text contains the actual value of the attribute.
  +         */
  +        {ErrorMsg.INVALID_NCNAME_ERR,
  +        "An attribute whose value must be an NCName had the value ''{0}''"},
  +
  +        /*
  +         * Note to translators:  An attribute with an incorrect value was
  +         * encountered.  The permitted value is one of the literal values
  +         * "xml", "html" or "text"; it is also permitted to have the form of
  +         * a QName that is not also an NCName.  The terms "method",
  +         * "xsl:output", "xml", "html" and "text" are keywords that must not
  +         * be translated.  The term "qname-but-not-ncname" is an XML syntactic
  +         * term.  The substitution text contains the actual value of the
  +         * attribute.
  +         */
  +        {ErrorMsg.INVALID_METHOD_IN_OUTPUT,
  +        "The method attribute of an <xsl:output> element had the value ''{0}''.  The value must be one of 'xml', 'html', 'text', or qname-but-not-ncname"}
       };
   
   
  
  
  
  1.25      +5 -2      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java
  
  Index: ErrorMsg.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- ErrorMsg.java	23 Feb 2004 21:33:15 -0000	1.24
  +++ ErrorMsg.java	24 Feb 2004 03:55:48 -0000	1.25
  @@ -144,7 +144,10 @@
       public static final String COULD_NOT_CREATE_TRANS_FACT = "COULD_NOT_CREATE_TRANS_FACT";
       public static final String TRANSLET_NAME_JAVA_CONFLICT =
                                                    "TRANSLET_NAME_JAVA_CONFLICT";
  -    
  +    public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR";
  +    public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR";
  +    public static final String INVALID_METHOD_IN_OUTPUT = "INVALID_METHOD_IN_OUTPUT";
  +                                                     
       // All error messages are localized and are stored in resource bundles.
       // This array and the following 4 strings are read from that bundle.
       private static ResourceBundle _bundle;
  
  
  
  1.15      +33 -1     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/Util.java
  
  Index: Util.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/Util.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Util.java	16 Feb 2004 22:26:45 -0000	1.14
  +++ Util.java	24 Feb 2004 03:55:48 -0000	1.15
  @@ -19,8 +19,11 @@
   
   package org.apache.xalan.xsltc.compiler.util;
   
  +import java.util.StringTokenizer;
  +
   import org.apache.bcel.generic.Type;
   import org.apache.xalan.xsltc.compiler.Constants;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * @author Jacek Ambroziak
  @@ -163,6 +166,35 @@
   	final int index = qname.lastIndexOf(":");
   	return (index > 0) ? qname.substring(0, index) : 
   	    Constants.EMPTYSTRING;
  +    } 
  +          
  +    /**
  +     * Checks if the string is a literal (i.e. not an AVT) or not.
  +     */
  +    public static boolean isLiteral(String str) {
  +        final int length = str.length();
  +        for (int i = 0; i < length - 1; i++) {
  +            if (str.charAt(i) == '{' && str.charAt(i + 1) != '{') {
  +        	return false;
  +            }
  +        }
  +        return true;
       }
  +    
  +    /**
  +     * Checks if the string is valid list of qnames
  +     */
  +    public static boolean isValidQNames(String str) {
  +        if ((str != null) && (!str.equals(Constants.EMPTYSTRING))) {
  +            final StringTokenizer tokens = new StringTokenizer(str);
  +            while (tokens.hasMoreTokens()) {
  +                if (!XMLChar.isValidQName(tokens.nextToken())) {
  +                    return false;
  +                }
  +            }
  +        }
  +        return true;
  +    }    
  +      	   
   }
   
  
  
  
  1.75      +109 -39   xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
  
  Index: BasisLibrary.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v
  retrieving revision 1.74
  retrieving revision 1.75
  diff -u -r1.74 -r1.75
  --- BasisLibrary.java	23 Feb 2004 15:57:27 -0000	1.74
  +++ BasisLibrary.java	24 Feb 2004 03:55:48 -0000	1.75
  @@ -46,7 +46,9 @@
   import org.w3c.dom.Document;
   import org.w3c.dom.NodeList;
   import org.xml.sax.SAXException;
  +import org.apache.xml.serializer.NamespaceMappings;
   import org.apache.xml.serializer.SerializationHandler;
  +import org.apache.xml.utils.XMLChar;
   
   /**
    * Standard XSLT functions. All standard functions expect the current node 
  @@ -1274,49 +1276,112 @@
   	    runTimeError(RUN_TIME_COPY_ERR);
   	}
       }
  -
  +    
  +    /**
  +     * Utility function to check if xsl:attribute has a valid qname
  +     * This method should only be invoked if the name attribute is an AVT
  +     */    
  +    public static void checkAttribQName(String name) {
  +        final int firstOccur = name.indexOf(":");
  +        final int lastOccur = name.lastIndexOf(":");
  +        final String localName = name.substring(lastOccur + 1);
  +        
  +        if (firstOccur > 0) {
  +            final String newPrefix = name.substring(0, firstOccur); 
  +        
  +            if (firstOccur != lastOccur) {
  +               final String oriPrefix = name.substring(firstOccur+1, lastOccur); 
  +                if (!XMLChar.isValidNCName(oriPrefix)) {
  +                    // even though the orignal prefix is ignored, it should still get checked for valid NCName
  +                    runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName);
  +                }
  +            }
  +            
  +            // prefix must be a valid NCName
  +            if (!XMLChar.isValidNCName(newPrefix)) {
  +                runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName); 
  +            }  
  +        }
  +                
  +        // local name must be a valid NCName and must not be XMLNS
  +        if ((!XMLChar.isValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) {
  +            runTimeError(INVALID_QNAME_ERR,localName); 
  +        }
  +    }
  +    
  +    /**
  +     * Utility function to check if a name is a valid ncname
  +     * This method should only be invoked if the attribute value is an AVT
  +     */    
  +    public static void checkNCName(String name) {
  +        if (!XMLChar.isValidNCName(name)) {
  +            runTimeError(INVALID_NCNAME_ERR,name); 
  +        }  
  +    }        
  +
  +    /**
  +     * Utility function to check if a name is a valid qname
  +     * This method should only be invoked if the attribute value is an AVT
  +     */    
  +    public static void checkQName(String name) {
  +        if (!XMLChar.isValidQName(name)) {
  +            runTimeError(INVALID_QNAME_ERR,name); 
  +        }  
  +    }
  +    
       /**
        * Utility function for the implementation of xsl:element.
        */
       public static String startXslElement(String qname, String namespace,
   	SerializationHandler handler, DOM dom, int node)
       {
  -	try {
  -	    // Get prefix from qname
  -	    String prefix;
  -	    final int index = qname.indexOf(':');
  -
  -	    if (index > 0) {
  -		prefix = qname.substring(0, index);
  -
  -		// Handle case when prefix is not known at compile time
  -		if (namespace == null || namespace.length() == 0) {
  -		    namespace = dom.lookupNamespace(node, prefix);
  -		}
  -
  -		handler.startElement(namespace, qname.substring(index+1),
  -                                     qname);
  -		handler.namespaceAfterStartElement(prefix, namespace); 
  -	    }
  -	    else {
  -		// Need to generate a prefix?
  -		if (namespace != null && namespace.length() > 0) {
  -		    prefix = generatePrefix();
  -		    qname = prefix + ':' + qname;   
  -		    handler.startElement(namespace, qname, qname);   
  -		    handler.namespaceAfterStartElement(prefix, namespace);
  -		}
  -		else {
  -		    handler.startElement(null, null, qname);   
  -		}
  -	    }
  -	}
  -	catch (SAXException e) {
  -	    throw new RuntimeException(e.getMessage());
  -	}
  -
  -	return qname;
  -    }
  +        try {
  +            // Get prefix from qname
  +            String prefix;
  +            final int index = qname.indexOf(':');
  +            
  +            if (index > 0) {
  +                prefix = qname.substring(0, index);
  +                
  +                // Handle case when prefix is not known at compile time
  +                if (namespace == null || namespace.length() == 0) {
  +                    try {
  +                        // not sure if this line of code ever works
  +                        namespace = dom.lookupNamespace(node, prefix);
  +                    }
  +                    catch(RuntimeException e) {
  +                        handler.flushPending();  // need to flush or else can't get namespacemappings
  +                        NamespaceMappings nm = handler.getNamespaceMappings();
  +                        namespace = nm.lookupNamespace(prefix);
  +                        if (namespace == null) {
  +                            runTimeError(NAMESPACE_PREFIX_ERR,prefix);
  +                        }
  +                    }
  +                }
  +                
  +                handler.startElement(namespace, qname.substring(index+1),
  +                                         qname);
  +                handler.namespaceAfterStartElement(prefix, namespace); 
  +            }
  +            else {                      
  +                // Need to generate a prefix?
  +                if (namespace != null && namespace.length() > 0) {
  +                    prefix = generatePrefix();
  +                    qname = prefix + ':' + qname;   
  +                    handler.startElement(namespace, qname, qname);   
  +                    handler.namespaceAfterStartElement(prefix, namespace);
  +                }
  +                else {
  +                    handler.startElement(null, null, qname);   
  +                }
  +            }
  +        }
  +        catch (SAXException e) {
  +            throw new RuntimeException(e.getMessage());
  +        }
  +    
  +        return qname;
  +    }    
   
       /**
        * This function is used in the execution of xsl:element
  @@ -1374,6 +1439,8 @@
                                              "UNSUPPORTED_EXT_ERR";
       public static final String UNKNOWN_TRANSLET_VERSION_ERR =
                                              "UNKNOWN_TRANSLET_VERSION_ERR";
  +    public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR";                                           
  +    public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR";
   
       // All error messages are localized and are stored in resource bundles.
       protected static ResourceBundle m_bundle;
  @@ -1447,7 +1514,10 @@
        * and thus get mapped to legal java variable names 
        */
       public static String mapQNameToJavaName (String base ) {
  -       return replace(base, ".-:/{}?#%*", new String[] { "$dot$", "$dash$" ,"$colon$", "$flash$","","$colon$","$ques$","$hash$","$per$","$aster$"});
  +       return replace(base, ".-:/{}?#%*",
  +                      new String[] { "$dot$", "$dash$" ,"$colon$", "$slash$",
  +                                     "","$colon$","$ques$","$hash$","$per$",
  +                                     "$aster$"});
   
       }
   
  
  
  
  1.10      +27 -8     xml-xalan/java/src/org/apache/xalan/xsltc/runtime/ErrorMessages.java
  
  Index: ErrorMessages.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/ErrorMessages.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ErrorMessages.java	16 Feb 2004 22:55:55 -0000	1.9
  +++ ErrorMessages.java	24 Feb 2004 03:55:48 -0000	1.10
  @@ -238,14 +238,33 @@
           "Unrecognized XSLTC extension ''{0}''"},
   
   
  -        //
  -        // Note to translators:  This error message is produced if the translet
  -        // class was compiled using a newer version of XSLTC and deployed for
  -        // execution with an older version of XSLTC.  The substitution text is
  -        // the name of the translet class.
  -        //
  +        /*
  +         * Note to translators:  This error message is produced if the translet
  +         * class was compiled using a newer version of XSLTC and deployed for
  +         * execution with an older version of XSLTC.  The substitution text is
  +         * the name of the translet class.
  +         */
           {BasisLibrary.UNKNOWN_TRANSLET_VERSION_ERR,
  -        "The specified translet, ''{0}'', was created using a version of XSLTC more recent than the version of the XSLTC run-time that is in use.  You must recompile the stylesheet or use a more recent version of XSLTC to run this translet."}
  +        "The specified translet, ''{0}'', was created using a version of XSLTC more recent than the version of the XSLTC run-time that is in use.  You must recompile the stylesheet or use a more recent version of XSLTC to run this translet."},
  +
  +        /*
  +         * Note to translators:  An attribute whose effective value is required
  +         * to be a "QName" had a value that was incorrect.
  +         * 'QName' is an XML syntactic term that must not be translated.  The
  +         * substitution text contains the actual value of the attribute.
  +         */
  +        {BasisLibrary.INVALID_QNAME_ERR,
  +        "An attribute whose value must be a QName had the value ''{0}''"},
  +
  +
  +        /*
  +         * Note to translators:  An attribute whose effective value is required
  +         * to be a "NCName" had a value that was incorrect.
  +         * 'NCName' is an XML syntactic term that must not be translated.  The
  +         * substitution text contains the actual value of the attribute.
  +         */
  +        {BasisLibrary.INVALID_NCNAME_ERR,
  +        "An attribute whose value must be an NCName had the value ''{0}''"},
       };
   
       public Object[][] getContents() {
  
  
  
  1.4       +23 -0     xml-xalan/java/src/org/apache/xml/utils/XMLChar.java
  
  Index: XMLChar.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/utils/XMLChar.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLChar.java	17 Feb 2004 04:21:14 -0000	1.3
  +++ XMLChar.java	24 Feb 2004 03:55:48 -0000	1.4
  @@ -639,5 +639,28 @@
           }
           return false;
       } // isValidIANAEncoding(String):boolean
  +    
  +   /**
  +     * Simple check to determine if qname is legal. If it returns false
  +     * then <param>str</param> is illegal; if it returns true then 
  +     * <param>str</param> is legal.
  +     */
  +    public static boolean isValidQName(String str) {
  +       
  +       final int colon = str.indexOf(':');
  +       
  +       if (colon == 0 || colon == str.length() - 1) {
  +           return false;
  +       }       
  +       
  +       if (colon > 0) {
  +           final String prefix = str.substring(0,colon);
  +           final String localPart = str.substring(colon+1);
  +           return isValidNCName(prefix) && isValidNCName(localPart);
  +       }
  +       else {
  +           return isValidNCName(str);
  +       }       
  +    }      
   
   } // class XMLChar
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org