1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.templates;
  58. //import org.w3c.dom.*;
  59. import org.apache.xml.dtm.DTM;
  60. import org.apache.xml.dtm.DTMIterator;
  61. import org.xml.sax.*;
  62. import org.apache.xpath.*;
  63. import org.apache.xpath.objects.XString;
  64. import org.apache.xpath.objects.XObject;
  65. import org.apache.xpath.objects.XNodeSet;
  66. import org.apache.xalan.trace.SelectionEvent;
  67. import org.apache.xalan.res.XSLTErrorResources;
  68. import org.apache.xalan.transformer.TransformerImpl;
  69. import org.apache.xalan.transformer.ResultTreeHandler;
  70. import org.apache.xml.utils.PrefixResolver;
  71. import org.apache.xml.utils.QName;
  72. import org.apache.xml.utils.XMLString;
  73. import javax.xml.transform.TransformerException;
  74. /**
  75. * <meta name="usage" content="advanced"/>
  76. * Implement xsl:value-of.
  77. * <pre>
  78. * <!ELEMENT xsl:value-of EMPTY>
  79. * <!ATTLIST xsl:value-of
  80. * select %expr; #REQUIRED
  81. * disable-output-escaping (yes|no) "no"
  82. * >
  83. * </pre>
  84. * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a>
  85. */
  86. public class ElemValueOf extends ElemTemplateElement
  87. {
  88. /**
  89. * The select expression to be executed.
  90. * @serial
  91. */
  92. private XPath m_selectExpression = null;
  93. /**
  94. * True if the pattern is a simple ".".
  95. * @serial
  96. */
  97. private boolean m_isDot = false;
  98. /**
  99. * Set the "select" attribute.
  100. * The required select attribute is an expression; this expression
  101. * is evaluated and the resulting object is converted to a
  102. * string as if by a call to the string function.
  103. *
  104. * @param v The value to set for the "select" attribute.
  105. */
  106. public void setSelect(XPath v)
  107. {
  108. if (null != v)
  109. {
  110. String s = v.getPatternString();
  111. m_isDot = (null != s) && s.equals(".");
  112. }
  113. m_selectExpression = v;
  114. }
  115. /**
  116. * Get the "select" attribute.
  117. * The required select attribute is an expression; this expression
  118. * is evaluated and the resulting object is converted to a
  119. * string as if by a call to the string function.
  120. *
  121. * @return The value of the "select" attribute.
  122. */
  123. public XPath getSelect()
  124. {
  125. return m_selectExpression;
  126. }
  127. /**
  128. * Tells if this element should disable escaping.
  129. * @serial
  130. */
  131. private boolean m_disableOutputEscaping = false;
  132. /**
  133. * Set the "disable-output-escaping" attribute.
  134. * Normally, the xml output method escapes & and < (and
  135. * possibly other characters) when outputting text nodes.
  136. * This ensures that the output is well-formed XML. However,
  137. * it is sometimes convenient to be able to produce output
  138. * that is almost, but not quite well-formed XML; for
  139. * example, the output may include ill-formed sections
  140. * which are intended to be transformed into well-formed
  141. * XML by a subsequent non-XML aware process. For this reason,
  142. * XSLT provides a mechanism for disabling output escaping.
  143. * An xsl:value-of or xsl:text element may have a
  144. * disable-output-escaping attribute; the allowed values
  145. * are yes or no; the default is no; if the value is yes,
  146. * then a text node generated by instantiating the xsl:value-of
  147. * or xsl:text element should be output without any escaping.
  148. * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
  149. *
  150. * @param v The value to set for the "disable-output-escaping" attribute.
  151. */
  152. public void setDisableOutputEscaping(boolean v)
  153. {
  154. m_disableOutputEscaping = v;
  155. }
  156. /**
  157. * Get the "disable-output-escaping" attribute.
  158. * Normally, the xml output method escapes & and < (and
  159. * possibly other characters) when outputting text nodes.
  160. * This ensures that the output is well-formed XML. However,
  161. * it is sometimes convenient to be able to produce output
  162. * that is almost, but not quite well-formed XML; for
  163. * example, the output may include ill-formed sections
  164. * which are intended to be transformed into well-formed
  165. * XML by a subsequent non-XML aware process. For this reason,
  166. * XSLT provides a mechanism for disabling output escaping.
  167. * An xsl:value-of or xsl:text element may have a
  168. * disable-output-escaping attribute; the allowed values
  169. * are yes or no; the default is no; if the value is yes,
  170. * then a text node generated by instantiating the xsl:value-of
  171. * or xsl:text element should be output without any escaping.
  172. * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
  173. *
  174. * @return The value of the "disable-output-escaping" attribute.
  175. */
  176. public boolean getDisableOutputEscaping()
  177. {
  178. return m_disableOutputEscaping;
  179. }
  180. /**
  181. * Get an integer representation of the element type.
  182. *
  183. * @return An integer representation of the element, defined in the
  184. * Constants class.
  185. * @see org.apache.xalan.templates.Constants
  186. */
  187. public int getXSLToken()
  188. {
  189. return Constants.ELEMNAME_VALUEOF;
  190. }
  191. /**
  192. * This function is called after everything else has been
  193. * recomposed, and allows the template to set remaining
  194. * values that may be based on some other property that
  195. * depends on recomposition.
  196. *
  197. * NEEDSDOC @param sroot
  198. *
  199. * @throws TransformerException
  200. */
  201. public void compose(StylesheetRoot sroot) throws TransformerException
  202. {
  203. super.compose(sroot);
  204. java.util.Vector vnames = sroot.getComposeState().getVariableNames();
  205. if (null != m_selectExpression)
  206. m_selectExpression.fixupVariables(
  207. vnames, sroot.getComposeState().getGlobalsSize());
  208. }
  209. /**
  210. * Return the node name.
  211. *
  212. * @return The node name
  213. */
  214. public String getNodeName()
  215. {
  216. return Constants.ELEMNAME_VALUEOF_STRING;
  217. }
  218. /**
  219. * Execute the string expression and copy the text to the
  220. * result tree.
  221. * The required select attribute is an expression; this expression
  222. * is evaluated and the resulting object is converted to a string
  223. * as if by a call to the string function. The string specifies
  224. * the string-value of the created text node. If the string is
  225. * empty, no text node will be created. The created text node will
  226. * be merged with any adjacent text nodes.
  227. * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a>
  228. *
  229. * @param transformer non-null reference to the the current transform-time state.
  230. * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
  231. * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
  232. *
  233. * @throws TransformerException
  234. */
  235. public void execute(TransformerImpl transformer) throws TransformerException
  236. {
  237. XPathContext xctxt = transformer.getXPathContext();
  238. ResultTreeHandler rth = transformer.getResultTreeHandler();
  239. if (TransformerImpl.S_DEBUG)
  240. transformer.getTraceManager().fireTraceEvent(this);
  241. try
  242. {
  243. // Optimize for "."
  244. if (false && m_isDot && !TransformerImpl.S_DEBUG)
  245. {
  246. int child = xctxt.getCurrentNode();
  247. DTM dtm = xctxt.getDTM(child);
  248. xctxt.pushCurrentNode(child);
  249. if (m_disableOutputEscaping)
  250. rth.processingInstruction(
  251. javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
  252. try
  253. {
  254. dtm.dispatchCharactersEvents(child, rth, false);
  255. }
  256. finally
  257. {
  258. if (m_disableOutputEscaping)
  259. rth.processingInstruction(
  260. javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
  261. xctxt.popCurrentNode();
  262. }
  263. }
  264. else
  265. {
  266. xctxt.pushNamespaceContext(this);
  267. int current = xctxt.getCurrentNode();
  268. xctxt.pushCurrentNodeAndExpression(current, current);
  269. if (m_disableOutputEscaping)
  270. rth.processingInstruction(
  271. javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
  272. try
  273. {
  274. Expression expr = m_selectExpression.getExpression();
  275. if (TransformerImpl.S_DEBUG)
  276. {
  277. XObject obj = expr.execute(xctxt);
  278. transformer.getTraceManager().fireSelectedEvent(current, this,
  279. "select", m_selectExpression, obj);
  280. obj.dispatchCharactersEvents(rth);
  281. }
  282. else
  283. {
  284. expr.executeCharsToContentHandler(xctxt, rth);
  285. }
  286. }
  287. finally
  288. {
  289. if (m_disableOutputEscaping)
  290. rth.processingInstruction(
  291. javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
  292. xctxt.popNamespaceContext();
  293. xctxt.popCurrentNodeAndExpression();
  294. }
  295. }
  296. }
  297. catch (SAXException se)
  298. {
  299. throw new TransformerException(se);
  300. }
  301. catch (RuntimeException re) {
  302. TransformerException te = new TransformerException(re);
  303. te.setLocator(this);
  304. throw te;
  305. }
  306. finally
  307. {
  308. if (TransformerImpl.S_DEBUG)
  309. transformer.getTraceManager().fireTraceEndEvent(this);
  310. }
  311. }
  312. /**
  313. * Add a child to the child list.
  314. *
  315. * @param newChild Child to add to children list
  316. *
  317. * @return Child just added to children list
  318. *
  319. * @throws DOMException
  320. */
  321. public ElemTemplateElement appendChild(ElemTemplateElement newChild)
  322. {
  323. error(XSLTErrorResources.ER_CANNOT_ADD,
  324. new Object[]{ newChild.getNodeName(),
  325. this.getNodeName() }); //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
  326. //" to " + this.m_elemName);
  327. return null;
  328. }
  329. /**
  330. * Call the children visitors.
  331. * @param visitor The visitor whose appropriate method will be called.
  332. */
  333. protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
  334. {
  335. if(callAttrs)
  336. m_selectExpression.getExpression().callVisitors(m_selectExpression, visitor);
  337. super.callChildVisitors(visitor, callAttrs);
  338. }
  339. }