1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id: ElemPI.java 468643 2006-10-28 06:56:03Z minchau $ 20 */ 21 package org.apache.xalan.templates; 22 23 import javax.xml.transform.TransformerException; 24 25 import org.apache.xalan.res.XSLTErrorResources; 26 import org.apache.xalan.transformer.TransformerImpl; 27 import org.apache.xml.utils.XML11Char; 28 import org.apache.xpath.XPathContext; 29 30 /** 31 * Implement xsl:processing-instruction. 32 * <pre> 33 * <!ELEMENT xsl:processing-instruction %char-template;> 34 * <!ATTLIST xsl:processing-instruction 35 * name %avt; #REQUIRED 36 * %space-att; 37 * > 38 * </pre> 39 * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions">section-Creating-Processing-Instructions in XSLT Specification</a> 40 * @xsl.usage advanced 41 */ 42 public class ElemPI extends ElemTemplateElement 43 { 44 static final long serialVersionUID = 5621976448020889825L; 45 46 /** 47 * The xsl:processing-instruction element has a required name 48 * attribute that specifies the name of the processing instruction node. 49 * The value of the name attribute is interpreted as an 50 * attribute value template. 51 * @serial 52 */ 53 private AVT m_name_atv = null; 54 55 /** 56 * Set the "name" attribute. 57 * DJD 58 * 59 * @param v Value for the name attribute 60 */ setName(AVT v)61 public void setName(AVT v) 62 { 63 m_name_atv = v; 64 } 65 66 /** 67 * Get the "name" attribute. 68 * DJD 69 * 70 * @return The value of the "name" attribute 71 */ getName()72 public AVT getName() 73 { 74 return m_name_atv; 75 } 76 77 /** 78 * This function is called after everything else has been 79 * recomposed, and allows the template to set remaining 80 * values that may be based on some other property that 81 * depends on recomposition. 82 */ compose(StylesheetRoot sroot)83 public void compose(StylesheetRoot sroot) throws TransformerException 84 { 85 super.compose(sroot); 86 java.util.Vector vnames = sroot.getComposeState().getVariableNames(); 87 if(null != m_name_atv) 88 m_name_atv.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize()); 89 } 90 91 92 93 /** 94 * Get an int constant identifying the type of element. 95 * @see org.apache.xalan.templates.Constants 96 * 97 * @return The token ID for the element 98 */ getXSLToken()99 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 */ getNodeName()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 */ execute( TransformerImpl transformer)124 public void execute( 125 TransformerImpl transformer) 126 throws TransformerException 127 { 128 129 XPathContext xctxt = transformer.getXPathContext(); 130 int sourceNode = xctxt.getCurrentNode(); 131 132 String piName = m_name_atv == null ? null : m_name_atv.evaluate(xctxt, sourceNode, this); 133 134 // Ignore processing instruction if name is null 135 if (piName == null) return; 136 137 if (piName.equalsIgnoreCase("xml")) 138 { 139 transformer.getMsgMgr().warn( 140 this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML, 141 new Object[]{ Constants.ATTRNAME_NAME, piName }); 142 return; 143 } 144 145 // Only check if an avt was used (ie. this wasn't checked at compose time.) 146 // Ignore processing instruction, if invalid 147 else if ((!m_name_atv.isSimple()) && (!XML11Char.isXML11ValidNCName(piName))) 148 { 149 transformer.getMsgMgr().warn( 150 this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME, 151 new Object[]{ Constants.ATTRNAME_NAME, piName }); 152 return; 153 } 154 155 // Note the content model is: 156 // <!ENTITY % instructions " 157 // %char-instructions; 158 // | xsl:processing-instruction 159 // | xsl:comment 160 // | xsl:element 161 // | xsl:attribute 162 // "> 163 String data = transformer.transformToString(this); 164 165 try 166 { 167 transformer.getResultTreeHandler().processingInstruction(piName, data); 168 } 169 catch(org.xml.sax.SAXException se) 170 { 171 throw new TransformerException(se); 172 } 173 } 174 175 /** 176 * Add a child to the child list. 177 * 178 * @param newChild Child to add to child list 179 * 180 * @return The child just added to the child list 181 * 182 * @throws DOMException 183 */ appendChild(ElemTemplateElement newChild)184 public ElemTemplateElement appendChild(ElemTemplateElement newChild) 185 { 186 187 int type = ((ElemTemplateElement) newChild).getXSLToken(); 188 189 switch (type) 190 { 191 192 // char-instructions 193 case Constants.ELEMNAME_TEXTLITERALRESULT : 194 case Constants.ELEMNAME_APPLY_TEMPLATES : 195 case Constants.ELEMNAME_APPLY_IMPORTS : 196 case Constants.ELEMNAME_CALLTEMPLATE : 197 case Constants.ELEMNAME_FOREACH : 198 case Constants.ELEMNAME_VALUEOF : 199 case Constants.ELEMNAME_COPY_OF : 200 case Constants.ELEMNAME_NUMBER : 201 case Constants.ELEMNAME_CHOOSE : 202 case Constants.ELEMNAME_IF : 203 case Constants.ELEMNAME_TEXT : 204 case Constants.ELEMNAME_COPY : 205 case Constants.ELEMNAME_VARIABLE : 206 case Constants.ELEMNAME_MESSAGE : 207 208 // instructions 209 // case Constants.ELEMNAME_PI: 210 // case Constants.ELEMNAME_COMMENT: 211 // case Constants.ELEMNAME_ELEMENT: 212 // case Constants.ELEMNAME_ATTRIBUTE: 213 break; 214 default : 215 error(XSLTErrorResources.ER_CANNOT_ADD, 216 new Object[]{ newChild.getNodeName(), 217 this.getNodeName() }); //"Can not add " +((ElemTemplateElement)newChild).m_elemName + 218 219 //" to " + this.m_elemName); 220 } 221 222 return super.appendChild(newChild); 223 } 224 } 225