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: ElemValueOf.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.dtm.DTM; 028 import org.apache.xml.serializer.SerializationHandler; 029 import org.apache.xpath.Expression; 030 import org.apache.xpath.XPath; 031 import org.apache.xpath.XPathContext; 032 import org.apache.xpath.objects.XObject; 033 import org.xml.sax.SAXException; 034 035 /** 036 * Implement xsl:value-of. 037 * <pre> 038 * <!ELEMENT xsl:value-of EMPTY> 039 * <!ATTLIST xsl:value-of 040 * select %expr; #REQUIRED 041 * disable-output-escaping (yes|no) "no" 042 * > 043 * </pre> 044 * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a> 045 * @xsl.usage advanced 046 */ 047 public class ElemValueOf extends ElemTemplateElement 048 { 049 static final long serialVersionUID = 3490728458007586786L; 050 051 /** 052 * The select expression to be executed. 053 * @serial 054 */ 055 private XPath m_selectExpression = null; 056 057 /** 058 * True if the pattern is a simple ".". 059 * @serial 060 */ 061 private boolean m_isDot = false; 062 063 /** 064 * Set the "select" attribute. 065 * The required select attribute is an expression; this expression 066 * is evaluated and the resulting object is converted to a 067 * string as if by a call to the string function. 068 * 069 * @param v The value to set for the "select" attribute. 070 */ 071 public void setSelect(XPath v) 072 { 073 074 if (null != v) 075 { 076 String s = v.getPatternString(); 077 078 m_isDot = (null != s) && s.equals("."); 079 } 080 081 m_selectExpression = v; 082 } 083 084 /** 085 * Get the "select" attribute. 086 * The required select attribute is an expression; this expression 087 * is evaluated and the resulting object is converted to a 088 * string as if by a call to the string function. 089 * 090 * @return The value of the "select" attribute. 091 */ 092 public XPath getSelect() 093 { 094 return m_selectExpression; 095 } 096 097 /** 098 * Tells if this element should disable escaping. 099 * @serial 100 */ 101 private boolean m_disableOutputEscaping = false; 102 103 /** 104 * Set the "disable-output-escaping" attribute. 105 * Normally, the xml output method escapes & and < (and 106 * possibly other characters) when outputting text nodes. 107 * This ensures that the output is well-formed XML. However, 108 * it is sometimes convenient to be able to produce output 109 * that is almost, but not quite well-formed XML; for 110 * example, the output may include ill-formed sections 111 * which are intended to be transformed into well-formed 112 * XML by a subsequent non-XML aware process. For this reason, 113 * XSLT provides a mechanism for disabling output escaping. 114 * An xsl:value-of or xsl:text element may have a 115 * disable-output-escaping attribute; the allowed values 116 * are yes or no; the default is no; if the value is yes, 117 * then a text node generated by instantiating the xsl:value-of 118 * or xsl:text element should be output without any escaping. 119 * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a> 120 * 121 * @param v The value to set for the "disable-output-escaping" attribute. 122 */ 123 public void setDisableOutputEscaping(boolean v) 124 { 125 m_disableOutputEscaping = v; 126 } 127 128 /** 129 * Get the "disable-output-escaping" attribute. 130 * Normally, the xml output method escapes & and < (and 131 * possibly other characters) when outputting text nodes. 132 * This ensures that the output is well-formed XML. However, 133 * it is sometimes convenient to be able to produce output 134 * that is almost, but not quite well-formed XML; for 135 * example, the output may include ill-formed sections 136 * which are intended to be transformed into well-formed 137 * XML by a subsequent non-XML aware process. For this reason, 138 * XSLT provides a mechanism for disabling output escaping. 139 * An xsl:value-of or xsl:text element may have a 140 * disable-output-escaping attribute; the allowed values 141 * are yes or no; the default is no; if the value is yes, 142 * then a text node generated by instantiating the xsl:value-of 143 * or xsl:text element should be output without any escaping. 144 * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a> 145 * 146 * @return The value of the "disable-output-escaping" attribute. 147 */ 148 public boolean getDisableOutputEscaping() 149 { 150 return m_disableOutputEscaping; 151 } 152 153 /** 154 * Get an integer representation of the element type. 155 * 156 * @return An integer representation of the element, defined in the 157 * Constants class. 158 * @see org.apache.xalan.templates.Constants 159 */ 160 public int getXSLToken() 161 { 162 return Constants.ELEMNAME_VALUEOF; 163 } 164 165 /** 166 * This function is called after everything else has been 167 * recomposed, and allows the template to set remaining 168 * values that may be based on some other property that 169 * depends on recomposition. 170 * 171 * NEEDSDOC @param sroot 172 * 173 * @throws TransformerException 174 */ 175 public void compose(StylesheetRoot sroot) throws TransformerException 176 { 177 178 super.compose(sroot); 179 180 java.util.Vector vnames = sroot.getComposeState().getVariableNames(); 181 182 if (null != m_selectExpression) 183 m_selectExpression.fixupVariables( 184 vnames, sroot.getComposeState().getGlobalsSize()); 185 } 186 187 /** 188 * Return the node name. 189 * 190 * @return The node name 191 */ 192 public String getNodeName() 193 { 194 return Constants.ELEMNAME_VALUEOF_STRING; 195 } 196 197 /** 198 * Execute the string expression and copy the text to the 199 * result tree. 200 * The required select attribute is an expression; this expression 201 * is evaluated and the resulting object is converted to a string 202 * as if by a call to the string function. The string specifies 203 * the string-value of the created text node. If the string is 204 * empty, no text node will be created. The created text node will 205 * be merged with any adjacent text nodes. 206 * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a> 207 * 208 * @param transformer non-null reference to the the current transform-time state. 209 * 210 * @throws TransformerException 211 */ 212 public void execute(TransformerImpl transformer) throws TransformerException 213 { 214 215 XPathContext xctxt = transformer.getXPathContext(); 216 SerializationHandler rth = transformer.getResultTreeHandler(); 217 218 if (transformer.getDebug()) 219 transformer.getTraceManager().fireTraceEvent(this); 220 221 try 222 { 223 // Optimize for "." 224 if (false && m_isDot && !transformer.getDebug()) 225 { 226 int child = xctxt.getCurrentNode(); 227 DTM dtm = xctxt.getDTM(child); 228 229 xctxt.pushCurrentNode(child); 230 231 if (m_disableOutputEscaping) 232 rth.processingInstruction( 233 javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, ""); 234 235 try 236 { 237 dtm.dispatchCharactersEvents(child, rth, false); 238 } 239 finally 240 { 241 if (m_disableOutputEscaping) 242 rth.processingInstruction( 243 javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, ""); 244 245 xctxt.popCurrentNode(); 246 } 247 } 248 else 249 { 250 xctxt.pushNamespaceContext(this); 251 252 int current = xctxt.getCurrentNode(); 253 254 xctxt.pushCurrentNodeAndExpression(current, current); 255 256 if (m_disableOutputEscaping) 257 rth.processingInstruction( 258 javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, ""); 259 260 try 261 { 262 Expression expr = m_selectExpression.getExpression(); 263 264 if (transformer.getDebug()) 265 { 266 XObject obj = expr.execute(xctxt); 267 268 transformer.getTraceManager().fireSelectedEvent(current, this, 269 "select", m_selectExpression, obj); 270 obj.dispatchCharactersEvents(rth); 271 } 272 else 273 { 274 expr.executeCharsToContentHandler(xctxt, rth); 275 } 276 } 277 finally 278 { 279 if (m_disableOutputEscaping) 280 rth.processingInstruction( 281 javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, ""); 282 283 xctxt.popNamespaceContext(); 284 xctxt.popCurrentNodeAndExpression(); 285 } 286 } 287 } 288 catch (SAXException se) 289 { 290 throw new TransformerException(se); 291 } 292 catch (RuntimeException re) { 293 TransformerException te = new TransformerException(re); 294 te.setLocator(this); 295 throw te; 296 } 297 finally 298 { 299 if (transformer.getDebug()) 300 transformer.getTraceManager().fireTraceEndEvent(this); 301 } 302 } 303 304 /** 305 * Add a child to the child list. 306 * 307 * @param newChild Child to add to children list 308 * 309 * @return Child just added to children list 310 * 311 * @throws DOMException 312 */ 313 public ElemTemplateElement appendChild(ElemTemplateElement newChild) 314 { 315 316 error(XSLTErrorResources.ER_CANNOT_ADD, 317 new Object[]{ newChild.getNodeName(), 318 this.getNodeName() }); //"Can not add " +((ElemTemplateElement)newChild).m_elemName + 319 320 //" to " + this.m_elemName); 321 return null; 322 } 323 324 /** 325 * Call the children visitors. 326 * @param visitor The visitor whose appropriate method will be called. 327 */ 328 protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs) 329 { 330 if(callAttrs) 331 m_selectExpression.getExpression().callVisitors(m_selectExpression, visitor); 332 super.callChildVisitors(visitor, callAttrs); 333 } 334 335 }