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: ElemValueOf.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.dtm.DTM; 28 import org.apache.xml.serializer.SerializationHandler; 29 import org.apache.xpath.Expression; 30 import org.apache.xpath.XPath; 31 import org.apache.xpath.XPathContext; 32 import org.apache.xpath.objects.XObject; 33 import org.xml.sax.SAXException; 34 35 /** 36 * Implement xsl:value-of. 37 * <pre> 38 * <!ELEMENT xsl:value-of EMPTY> 39 * <!ATTLIST xsl:value-of 40 * select %expr; #REQUIRED 41 * disable-output-escaping (yes|no) "no" 42 * > 43 * </pre> 44 * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a> 45 * @xsl.usage advanced 46 */ 47 public class ElemValueOf extends ElemTemplateElement 48 { 49 static final long serialVersionUID = 3490728458007586786L; 50 51 /** 52 * The select expression to be executed. 53 * @serial 54 */ 55 private XPath m_selectExpression = null; 56 57 /** 58 * True if the pattern is a simple ".". 59 * @serial 60 */ 61 private boolean m_isDot = false; 62 63 /** 64 * Set the "select" attribute. 65 * The required select attribute is an expression; this expression 66 * is evaluated and the resulting object is converted to a 67 * string as if by a call to the string function. 68 * 69 * @param v The value to set for the "select" attribute. 70 */ 71 public void setSelect(XPath v) 72 { 73 74 if (null != v) 75 { 76 String s = v.getPatternString(); 77 78 m_isDot = (null != s) && s.equals("."); 79 } 80 81 m_selectExpression = v; 82 } 83 84 /** 85 * Get the "select" attribute. 86 * The required select attribute is an expression; this expression 87 * is evaluated and the resulting object is converted to a 88 * string as if by a call to the string function. 89 * 90 * @return The value of the "select" attribute. 91 */ 92 public XPath getSelect() 93 { 94 return m_selectExpression; 95 } 96 97 /** 98 * Tells if this element should disable escaping. 99 * @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 try 219 { 220 // Optimize for "." 221 xctxt.pushNamespaceContext(this); 222 223 int current = xctxt.getCurrentNode(); 224 225 xctxt.pushCurrentNodeAndExpression(current, current); 226 227 if (m_disableOutputEscaping) 228 rth.processingInstruction( 229 javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, ""); 230 231 try 232 { 233 Expression expr = m_selectExpression.getExpression(); 234 235 expr.executeCharsToContentHandler(xctxt, rth); 236 } 237 finally 238 { 239 if (m_disableOutputEscaping) 240 rth.processingInstruction( 241 javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, ""); 242 243 xctxt.popNamespaceContext(); 244 xctxt.popCurrentNodeAndExpression(); 245 } 246 } 247 catch (SAXException se) 248 { 249 throw new TransformerException(se); 250 } 251 catch (RuntimeException re) { 252 TransformerException te = new TransformerException(re); 253 te.setLocator(this); 254 throw te; 255 } 256 } 257 258 /** 259 * Add a child to the child list. 260 * 261 * @param newChild Child to add to children list 262 * 263 * @return Child just added to children list 264 * 265 * @throws DOMException 266 */ 267 public ElemTemplateElement appendChild(ElemTemplateElement newChild) 268 { 269 270 error(XSLTErrorResources.ER_CANNOT_ADD, 271 new Object[]{ newChild.getNodeName(), 272 this.getNodeName() }); //"Can not add " +((ElemTemplateElement)newChild).m_elemName + 273 274 //" to " + this.m_elemName); 275 return null; 276 } 277 278 /** 279 * Call the children visitors. 280 * @param visitor The visitor whose appropriate method will be called. 281 */ 282 protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs) 283 { 284 if(callAttrs) 285 m_selectExpression.getExpression().callVisitors(m_selectExpression, visitor); 286 super.callChildVisitors(visitor, callAttrs); 287 } 288 289 } 290