001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: ElemPI.java 468643 2006-10-28 06:56:03Z minchau $ 020 */ 021 package org.apache.xalan.templates; 022 023 import javax.xml.transform.TransformerException; 024 025 import org.apache.xalan.res.XSLTErrorResources; 026 import org.apache.xalan.transformer.TransformerImpl; 027 import org.apache.xml.utils.XML11Char; 028 import org.apache.xpath.XPathContext; 029 030 /** 031 * Implement xsl:processing-instruction. 032 * <pre> 033 * <!ELEMENT xsl:processing-instruction %char-template;> 034 * <!ATTLIST xsl:processing-instruction 035 * name %avt; #REQUIRED 036 * %space-att; 037 * > 038 * </pre> 039 * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions">section-Creating-Processing-Instructions in XSLT Specification</a> 040 * @xsl.usage advanced 041 */ 042 public class ElemPI extends ElemTemplateElement 043 { 044 static final long serialVersionUID = 5621976448020889825L; 045 046 /** 047 * The xsl:processing-instruction element has a required name 048 * attribute that specifies the name of the processing instruction node. 049 * The value of the name attribute is interpreted as an 050 * attribute value template. 051 * @serial 052 */ 053 private AVT m_name_atv = null; 054 055 /** 056 * Set the "name" attribute. 057 * DJD 058 * 059 * @param v Value for the name attribute 060 */ 061 public void setName(AVT v) 062 { 063 m_name_atv = v; 064 } 065 066 /** 067 * Get the "name" attribute. 068 * DJD 069 * 070 * @return The value of the "name" attribute 071 */ 072 public AVT getName() 073 { 074 return m_name_atv; 075 } 076 077 /** 078 * This function is called after everything else has been 079 * recomposed, and allows the template to set remaining 080 * values that may be based on some other property that 081 * depends on recomposition. 082 */ 083 public void compose(StylesheetRoot sroot) throws TransformerException 084 { 085 super.compose(sroot); 086 java.util.Vector vnames = sroot.getComposeState().getVariableNames(); 087 if(null != m_name_atv) 088 m_name_atv.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize()); 089 } 090 091 092 093 /** 094 * Get an int constant identifying the type of element. 095 * @see org.apache.xalan.templates.Constants 096 * 097 * @return The token ID for the element 098 */ 099 public int getXSLToken() 100 { 101 return Constants.ELEMNAME_PI; 102 } 103 104 /** 105 * Return the node name. 106 * 107 * @return The element's name 108 */ 109 public String getNodeName() 110 { 111 return Constants.ELEMNAME_PI_STRING; 112 } 113 114 /** 115 * Create a processing instruction in the result tree. 116 * The content of the xsl:processing-instruction element is a 117 * template for the string-value of the processing instruction node. 118 * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions">section-Creating-Processing-Instructions in XSLT Specification</a> 119 * 120 * @param transformer non-null reference to the the current transform-time state. 121 * 122 * @throws TransformerException 123 */ 124 public void execute( 125 TransformerImpl transformer) 126 throws TransformerException 127 { 128 129 if (transformer.getDebug()) 130 transformer.getTraceManager().fireTraceEvent(this); 131 132 XPathContext xctxt = transformer.getXPathContext(); 133 int sourceNode = xctxt.getCurrentNode(); 134 135 String piName = m_name_atv == null ? null : m_name_atv.evaluate(xctxt, sourceNode, this); 136 137 // Ignore processing instruction if name is null 138 if (piName == null) return; 139 140 if (piName.equalsIgnoreCase("xml")) 141 { 142 transformer.getMsgMgr().warn( 143 this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML, 144 new Object[]{ Constants.ATTRNAME_NAME, piName }); 145 return; 146 } 147 148 // Only check if an avt was used (ie. this wasn't checked at compose time.) 149 // Ignore processing instruction, if invalid 150 else if ((!m_name_atv.isSimple()) && (!XML11Char.isXML11ValidNCName(piName))) 151 { 152 transformer.getMsgMgr().warn( 153 this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME, 154 new Object[]{ Constants.ATTRNAME_NAME, piName }); 155 return; 156 } 157 158 // Note the content model is: 159 // <!ENTITY % instructions " 160 // %char-instructions; 161 // | xsl:processing-instruction 162 // | xsl:comment 163 // | xsl:element 164 // | xsl:attribute 165 // "> 166 String data = transformer.transformToString(this); 167 168 try 169 { 170 transformer.getResultTreeHandler().processingInstruction(piName, data); 171 } 172 catch(org.xml.sax.SAXException se) 173 { 174 throw new TransformerException(se); 175 } 176 177 if (transformer.getDebug()) 178 transformer.getTraceManager().fireTraceEndEvent(this); 179 } 180 181 /** 182 * Add a child to the child list. 183 * 184 * @param newChild Child to add to child list 185 * 186 * @return The child just added to the child list 187 * 188 * @throws DOMException 189 */ 190 public ElemTemplateElement appendChild(ElemTemplateElement newChild) 191 { 192 193 int type = ((ElemTemplateElement) newChild).getXSLToken(); 194 195 switch (type) 196 { 197 198 // char-instructions 199 case Constants.ELEMNAME_TEXTLITERALRESULT : 200 case Constants.ELEMNAME_APPLY_TEMPLATES : 201 case Constants.ELEMNAME_APPLY_IMPORTS : 202 case Constants.ELEMNAME_CALLTEMPLATE : 203 case Constants.ELEMNAME_FOREACH : 204 case Constants.ELEMNAME_VALUEOF : 205 case Constants.ELEMNAME_COPY_OF : 206 case Constants.ELEMNAME_NUMBER : 207 case Constants.ELEMNAME_CHOOSE : 208 case Constants.ELEMNAME_IF : 209 case Constants.ELEMNAME_TEXT : 210 case Constants.ELEMNAME_COPY : 211 case Constants.ELEMNAME_VARIABLE : 212 case Constants.ELEMNAME_MESSAGE : 213 214 // instructions 215 // case Constants.ELEMNAME_PI: 216 // case Constants.ELEMNAME_COMMENT: 217 // case Constants.ELEMNAME_ELEMENT: 218 // case Constants.ELEMNAME_ATTRIBUTE: 219 break; 220 default : 221 error(XSLTErrorResources.ER_CANNOT_ADD, 222 new Object[]{ newChild.getNodeName(), 223 this.getNodeName() }); //"Can not add " +((ElemTemplateElement)newChild).m_elemName + 224 225 //" to " + this.m_elemName); 226 } 227 228 return super.appendChild(newChild); 229 } 230 }