XslTransformTests.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. //
  2. // System.Xml.Xsl.XslTransformTests.cs
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. // (C) 2002 Atsushi Enomoto
  8. //
  9. using System;
  10. using System.Globalization;
  11. using System.IO;
  12. using System.Text;
  13. using System.Xml;
  14. using System.Xml.XPath;
  15. using System.Xml.Xsl;
  16. using NUnit.Framework;
  17. namespace MonoTests.System.Xml.Xsl
  18. {
  19. [TestFixture]
  20. public class XslTransformTests : Assertion
  21. {
  22. XmlDocument doc;
  23. XslTransform xslt;
  24. XmlDocument result;
  25. [SetUp]
  26. public void GetReady()
  27. {
  28. doc = new XmlDocument ();
  29. xslt = new XslTransform ();
  30. result = new XmlDocument ();
  31. }
  32. [Test]
  33. public void TestBasicTransform ()
  34. {
  35. doc.LoadXml ("<root/>");
  36. xslt.Load ("Test/XmlFiles/xsl/empty.xsl");
  37. xslt.Transform ("Test/XmlFiles/xsl/empty.xsl", "Test/XmlFiles/xsl/result.xml");
  38. result.Load ("Test/XmlFiles/xsl/result.xml");
  39. AssertEquals ("count", 2, result.ChildNodes.Count);
  40. }
  41. [Test]
  42. [ExpectedException (typeof (XsltCompileException))]
  43. public void InvalidStylesheet ()
  44. {
  45. XmlDocument doc = new XmlDocument ();
  46. doc.LoadXml ("<xsl:element xmlns:xsl='http://www.w3.org/1999/XSL/Transform' />");
  47. XslTransform t = new XslTransform ();
  48. t.Load (doc);
  49. }
  50. [Test]
  51. [ExpectedException (typeof (XsltCompileException))]
  52. public void EmptyStylesheet ()
  53. {
  54. XmlDocument doc = new XmlDocument ();
  55. XslTransform t = new XslTransform ();
  56. t.Load (doc);
  57. }
  58. [Test]
  59. [ExpectedException (typeof (XsltCompileException))]
  60. public void InvalidStylesheet2 ()
  61. {
  62. string xml = @"<root>text</root>";
  63. string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  64. <xsl:template match='/root'>
  65. <xsl:call-template name='foo'>
  66. <xsl:with-param name='name' value='text()' />
  67. </xsl:call-template>
  68. </xsl:template>
  69. <xsl:template name='foo'>
  70. <xsl:param name='name' />
  71. <result>
  72. <xsl:if test='1'>
  73. <xsl:variable name='last' value='text()' />
  74. <xsl:value-of select='$last' />
  75. </xsl:if>
  76. </result>
  77. </xsl:template>
  78. </xsl:stylesheet>
  79. ";
  80. XslTransform xslt = new XslTransform ();
  81. xslt.Load (new XPathDocument (new XmlTextReader (xsl, XmlNodeType.Document, null)));
  82. }
  83. [Test()]
  84. [Category ("NotWorking")] // it depends on "mcs" existence
  85. public void MsxslTest() {
  86. string _styleSheet = @"
  87. <xslt:stylesheet xmlns:xslt=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"" xmlns:msxsl=""urn:schemas-microsoft-com:xslt"" xmlns:stringutils=""urn:schemas-sourceforge.net-blah"">
  88. <xslt:output method=""text"" />
  89. <msxsl:script language=""C#"" implements-prefix=""stringutils"">
  90. <![CDATA[
  91. string PadRight( string str, int padding) {
  92. return str.PadRight(padding);
  93. }
  94. ]]>
  95. </msxsl:script>
  96. <xslt:template match=""test"">
  97. <xslt:value-of select=""stringutils:PadRight(@name, 20)"" />
  98. </xslt:template>
  99. </xslt:stylesheet>";
  100. StringReader stringReader = new StringReader(_styleSheet);
  101. XslTransform transform = new XslTransform();
  102. XmlTextReader reader = new XmlTextReader(stringReader);
  103. transform.Load(reader, new XmlUrlResolver(), AppDomain.CurrentDomain.Evidence);
  104. StringBuilder sb = new StringBuilder();
  105. StringWriter writer = new StringWriter(sb, CultureInfo.InvariantCulture);
  106. XsltArgumentList arguments = new XsltArgumentList();
  107. XmlDocument xmlDoc = new XmlDocument();
  108. xmlDoc.LoadXml("<test name=\"test\" />");
  109. // Do transformation
  110. transform.Transform(xmlDoc, new XsltArgumentList(), writer, new XmlUrlResolver());
  111. AssertEquals("test".PadRight(20), sb.ToString());
  112. }
  113. [Test]
  114. public void MSXslNodeSet ()
  115. {
  116. string xsl = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
  117. <xsl:template match='/'>
  118. <root>
  119. <xsl:variable name='var'>
  120. <xsl:copy-of select='root/foo' />
  121. </xsl:variable>
  122. <xsl:for-each select='msxsl:node-set($var)/foo'>
  123. <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
  124. </xsl:for-each>
  125. </root>
  126. </xsl:template>
  127. </xsl:stylesheet>";
  128. StringWriter sw = new StringWriter ();
  129. XslTransform t = new XslTransform ();
  130. t.Load (new XPathDocument (new StringReader (xsl)));
  131. t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
  132. AssertEquals (@"<?xml version=""1.0"" encoding=""utf-16""?><root xmlns:msxsl=""urn:schemas-microsoft-com:xslt"">foo: Afoo: Bfoo: C</root>", sw.ToString ());
  133. }
  134. [Test]
  135. [Category ("NotDotNet")]
  136. // Actually MS.NET here throws XsltException, but Mono returns
  137. // XPathException (since XPath evaluation engine generally
  138. // catches (should catch) static error. It is implementation
  139. // dependent matter.
  140. [ExpectedException (typeof (XPathException))]
  141. public void MSXslNodeSetRejectsNodeSet ()
  142. {
  143. string xsl = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
  144. <xsl:template match='/'>
  145. <root>
  146. <!-- msxsl:node-set() does not accept a node set -->
  147. <xsl:for-each select='msxsl:node-set(root/foo)'>
  148. <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
  149. </xsl:for-each>
  150. </root>
  151. </xsl:template>
  152. </xsl:stylesheet>";
  153. StringWriter sw = new StringWriter ();
  154. XslTransform t = new XslTransform ();
  155. t.Load (new XPathDocument (new StringReader (xsl)));
  156. t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
  157. }
  158. [Test]
  159. public void EvaluateEmptyVariableAsBoolean ()
  160. {
  161. string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  162. <xsl:template match='/'>
  163. <xsl:variable name='var'><empty /></xsl:variable>
  164. <root><xsl:if test='$var'>true</xsl:if></root>
  165. </xsl:template>
  166. </xsl:stylesheet>";
  167. XslTransform t = new XslTransform ();
  168. t.Load (new XPathDocument (new StringReader (xsl)));
  169. StringWriter sw = new StringWriter ();
  170. t.Transform (
  171. new XPathDocument (new StringReader ("<root/>")),
  172. null,
  173. sw);
  174. Assert (sw.ToString ().IndexOf ("true") > 0);
  175. }
  176. [Test]
  177. [ExpectedException (typeof (XsltCompileException))]
  178. public void NotAllowedPatternAxis ()
  179. {
  180. string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  181. <xsl:template match='/descendant-or-self::node()/elem'>
  182. <ERROR/>
  183. </xsl:template>
  184. </xsl:stylesheet>";
  185. new XslTransform ().Load (new XPathDocument (
  186. new StringReader (xsl)));
  187. }
  188. [Test]
  189. [ExpectedException (typeof (XsltCompileException))]
  190. public void ImportIncorrectlyLocated ()
  191. {
  192. string xsl = @"<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  193. <xsl:template match='/'></xsl:template>
  194. <xsl:import href='dummy.xsl' />
  195. </xsl:transform>";
  196. new XslTransform ().Load (new XPathDocument (
  197. new StringReader (xsl)));
  198. }
  199. [Test]
  200. [Category ("NotDotNet")]
  201. public void DontHoldStylesheetReference ()
  202. {
  203. // This test is optional. Examines whether Load() does
  204. // not hold loaded stylesheet XPathNavigator internally.
  205. XslTransform t = new XslTransform ();
  206. WeakReference wr = StylesheetLoad (t, "<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'/>");
  207. GC.Collect (0);
  208. GC.Collect (2);
  209. Assert ("load", !wr.IsAlive);
  210. wr = StylesheetTransform (t, "<root/>");
  211. GC.Collect (0);
  212. GC.Collect (2);
  213. Assert ("transform", !wr.IsAlive);
  214. }
  215. private WeakReference StylesheetLoad (XslTransform t, string xsl)
  216. {
  217. XPathDocument doc = new XPathDocument (
  218. new StringReader (xsl));
  219. WeakReference wr = new WeakReference (doc);
  220. t.Load (doc);
  221. return wr;
  222. }
  223. private WeakReference StylesheetTransform (XslTransform t, string xml)
  224. {
  225. XPathDocument doc = new XPathDocument (
  226. new StringReader (xml));
  227. WeakReference wr = new WeakReference (doc);
  228. t.Transform (doc, null, TextWriter.Null, null);
  229. return wr;
  230. }
  231. [Test]
  232. // bug #75663.
  233. public void ErrorOnDocumentResolution ()
  234. {
  235. // XslTransform recovers from errors on document resolution.
  236. string xslText = @"<xsl:stylesheet
  237. xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
  238. version='1.0'>
  239. <xsl:variable name='n'
  240. select='document(""notexist.xml"")' />
  241. <xsl:template match='/'>xx</xsl:template>
  242. </xsl:stylesheet>";
  243. string xmlText = @"<root />";
  244. XslTransform transform = new XslTransform ();
  245. XPathDocument doc = new XPathDocument (
  246. new XmlTextReader ("a.xsl", new StringReader (xslText)));
  247. transform.Load (doc);
  248. XPathDocument xmlDocument = new XPathDocument (new StringReader (xmlText));
  249. transform.Transform (xmlDocument, null, TextWriter.Null);
  250. }
  251. }
  252. }