Make a copy of the old ZipLib
[mono.git] / mcs / class / System.XML / Test / System.Xml.Xsl / XslTransformTests.cs
1 //
2 // System.Xml.Xsl.XslTransformTests.cs
3 //
4 // Author:
5 //   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // (C) 2002 Atsushi Enomoto
8 //
9
10 using System;
11 using System.Globalization;
12 using System.IO;
13 using System.Text;
14 using System.Xml;
15 using System.Xml.XPath;
16 using System.Xml.Xsl;
17 using NUnit.Framework;
18
19 namespace MonoTests.System.Xml.Xsl
20 {
21         [TestFixture]
22         public class XslTransformTests : Assertion
23         {
24                 XmlDocument doc;
25                 XslTransform xslt;
26                 XmlDocument result;
27
28                 [SetUp]
29                 public void GetReady()
30                 {
31                         doc = new XmlDocument ();
32                         xslt = new XslTransform ();
33                         result = new XmlDocument ();
34                 }
35
36                 [Test]
37                 public void TestBasicTransform ()
38                 {
39                         doc.LoadXml ("<root/>");
40                         xslt.Load ("Test/XmlFiles/xsl/empty.xsl");
41                         xslt.Transform ("Test/XmlFiles/xsl/empty.xsl", "Test/XmlFiles/xsl/result.xml");
42                         result.Load ("Test/XmlFiles/xsl/result.xml");
43                         AssertEquals ("count", 2, result.ChildNodes.Count);
44                 }
45
46                 [Test]
47                 [ExpectedException (typeof (XsltCompileException))]
48                 public void InvalidStylesheet ()
49                 {
50                         XmlDocument doc = new XmlDocument ();
51                         doc.LoadXml ("<xsl:element xmlns:xsl='http://www.w3.org/1999/XSL/Transform' />");
52                         XslTransform t = new XslTransform ();
53                         t.Load (doc);
54                 }
55
56                 [Test]
57                 [ExpectedException (typeof (XsltCompileException))]
58                 public void EmptyStylesheet ()
59                 {
60                         XmlDocument doc = new XmlDocument ();
61                         XslTransform t = new XslTransform ();
62                         t.Load (doc);
63                 }
64
65                 [Test]
66                 [ExpectedException (typeof (XsltCompileException))]
67                 public void InvalidStylesheet2 ()
68                 {
69                         string xml = @"<root>text</root>";
70                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
71         <xsl:template match='/root'>
72                 <xsl:call-template name='foo'>
73                         <xsl:with-param name='name' value='text()' />
74                 </xsl:call-template>
75         </xsl:template>
76         <xsl:template name='foo'>
77                 <xsl:param name='name' />
78                 <result>
79                         <xsl:if test='1'>
80                                 <xsl:variable name='last' value='text()' />
81                                 <xsl:value-of select='$last' />
82                         </xsl:if>
83                 </result>
84         </xsl:template>
85 </xsl:stylesheet>
86 ";
87                         XslTransform xslt = new XslTransform ();
88                         xslt.Load (new XPathDocument (new XmlTextReader (xsl, XmlNodeType.Document, null)));
89                 }
90
91                 [Test()]\r
92                 [Category ("NotWorking")] // it depends on "mcs" existence
93                 public void MsxslTest() {\r
94                         string _styleSheet = @"\r
95                         <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"">\r
96                                 <xslt:output method=""text"" />\r
97                                 <msxsl:script language=""C#"" implements-prefix=""stringutils"">\r
98                                         <![CDATA[\r
99                                                 string PadRight( string str, int padding) {\r
100                                                     return str.PadRight(padding);\r
101                                                 }\r
102                                         ]]>\r
103                                 </msxsl:script>\r
104                                 <xslt:template match=""test"">\r
105                                         <xslt:value-of select=""stringutils:PadRight(@name, 20)"" />\r
106                                 </xslt:template>\r
107                         </xslt:stylesheet>";\r
108 \r
109                         StringReader stringReader = new StringReader(_styleSheet);\r
110                         \r
111                         XslTransform transform = new XslTransform();\r
112                         XmlTextReader reader = new XmlTextReader(stringReader);\r
113                         transform.Load(reader, new XmlUrlResolver(), AppDomain.CurrentDomain.Evidence);\r
114 \r
115                         StringBuilder sb = new StringBuilder();\r
116                         StringWriter writer = new StringWriter(sb, CultureInfo.InvariantCulture);\r
117                         XsltArgumentList arguments = new XsltArgumentList();\r
118 \r
119                         XmlDocument xmlDoc = new XmlDocument();\r
120                         xmlDoc.LoadXml("<test name=\"test\" />");\r
121 \r
122                         // Do transformation\r
123                         transform.Transform(xmlDoc, new XsltArgumentList(), writer, new XmlUrlResolver());\r
124 \r
125 \r
126                         AssertEquals("test".PadRight(20), sb.ToString());\r
127                 }\r
128 \r
129                 [Test]\r
130                 public void MSXslNodeSet ()
131                 {
132                         string xsl = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
133 <xsl:template match='/'>
134 <root>
135         <xsl:variable name='var'>
136                 <xsl:copy-of select='root/foo' />
137         </xsl:variable>
138         <xsl:for-each select='msxsl:node-set($var)/foo'>
139                 <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
140         </xsl:for-each>
141 </root>
142 </xsl:template>
143 </xsl:stylesheet>";
144                         StringWriter sw = new StringWriter ();
145                         XslTransform t = new XslTransform ();
146                         t.Load (new XPathDocument (new StringReader (xsl)));
147                         t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
148                         AssertEquals (@"<?xml version=""1.0"" encoding=""utf-16""?><root xmlns:msxsl=""urn:schemas-microsoft-com:xslt"">foo: Afoo: Bfoo: C</root>", sw.ToString ());
149                 }
150 \r
151                 [Test]
152                 [Category ("NotDotNet")]\r
153                 // Actually MS.NET here throws XsltException, but Mono returns\r
154                 // XPathException (since XPath evaluation engine generally
155                 // catches (should catch) static error. It is implementation \r
156                 // dependent matter.\r
157                 [ExpectedException (typeof (XPathException))]\r
158                 public void MSXslNodeSetRejectsNodeSet ()
159                 {
160                         string xsl = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
161 <xsl:template match='/'>
162 <root>
163         <!-- msxsl:node-set() does not accept a node set -->
164         <xsl:for-each select='msxsl:node-set(root/foo)'>
165                 <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
166         </xsl:for-each>
167 </root>
168 </xsl:template>
169 </xsl:stylesheet>";
170                         StringWriter sw = new StringWriter ();
171                         XslTransform t = new XslTransform ();
172                         t.Load (new XPathDocument (new StringReader (xsl)));
173                         t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
174                 }
175
176                 [Test]
177                 public void EvaluateEmptyVariableAsBoolean ()
178                 {
179                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
180 <xsl:template match='/'>
181 <xsl:variable name='var'><empty /></xsl:variable>
182   <root><xsl:if test='$var'>true</xsl:if></root>
183 </xsl:template>
184 </xsl:stylesheet>";
185                         XslTransform t = new XslTransform ();
186                         t.Load (new XPathDocument (new StringReader (xsl)));
187                         StringWriter sw = new StringWriter ();
188                         t.Transform (
189                                 new XPathDocument (new StringReader ("<root/>")),
190                                 null,
191                                 sw);
192                         Assert (sw.ToString ().IndexOf ("true") > 0);
193                 }
194
195                 [Test]
196                 [ExpectedException (typeof (XsltCompileException))]
197                 public void NotAllowedPatternAxis ()
198                 {
199                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
200 <xsl:template match='/descendant-or-self::node()/elem'>
201 <ERROR/>
202 </xsl:template>
203 </xsl:stylesheet>";
204                         new XslTransform ().Load (new XPathDocument (
205                                 new StringReader (xsl)));
206                 }
207
208                 [Test]
209                 [ExpectedException (typeof (XsltCompileException))]
210                 public void ImportIncorrectlyLocated ()
211                 {
212                         string xsl = @"<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
213 <xsl:template match='/'></xsl:template>
214 <xsl:import href='dummy.xsl' />
215 </xsl:transform>";
216                         new XslTransform ().Load (new XPathDocument (
217                                 new StringReader (xsl)));
218                 }
219
220                 private WeakReference StylesheetLoad (XslTransform t, string xsl)
221                 {
222                         XPathDocument doc = new XPathDocument (
223                                 new StringReader (xsl));
224                         WeakReference wr = new WeakReference (doc);
225                         t.Load (doc);
226                         return wr;
227                 }
228
229                 private WeakReference StylesheetTransform (XslTransform t, string xml)
230                 {
231                         XPathDocument doc = new XPathDocument (
232                                 new StringReader (xml));
233                         WeakReference wr = new WeakReference (doc);
234                         t.Transform (doc, null, TextWriter.Null, null);
235                         return wr;
236                 }
237
238                 [Test]
239                 // bug #75663.
240                 public void ErrorOnDocumentResolution ()
241                 {
242                         // XslTransform recovers from errors on document resolution.
243                         string xslText = @"<xsl:stylesheet
244                                 xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
245                                 version='1.0'>
246                                 <xsl:variable name='n'
247                                         select='document(""notexist.xml"")' />
248                                 <xsl:template match='/'>xx</xsl:template>
249                                 </xsl:stylesheet>";
250                         string xmlText = @"<root />";
251                         XslTransform transform = new XslTransform ();
252                         XPathDocument doc = new XPathDocument (
253                                 new XmlTextReader ("a.xsl", new StringReader (xslText)));
254                         transform.Load (doc);
255                         XPathDocument xmlDocument = new XPathDocument (new StringReader (xmlText));
256                         transform.Transform (xmlDocument, null, TextWriter.Null);
257                 }
258
259                 // bug #76046
260                 [Test]
261                 public void LoadStyleFromNonRoot ()
262                 {
263                         XmlDocument doc = new XmlDocument ();
264                         XslTransform xslt = new XslTransform ();
265                         doc.LoadXml ("<root><dummy /><xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' /></root>");
266                         XmlNode node = doc.ChildNodes [0].ChildNodes [1];
267                         xslt.Load (node, null, null);
268                 }
269
270                 [Test]
271                 public void ReturnEmptyResultsAsXmlReader ()
272                 {
273                         // bug #76115
274                         XmlDocument doc = new XmlDocument ();
275                         doc.LoadXml ("<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' />");
276                         XslTransform xslt = new XslTransform ();
277                         xslt.Load (doc, null, null);
278                         XmlReader reader = xslt.Transform(doc, null, new XmlUrlResolver ());
279                         reader.Read ();
280
281                         // another case - with xsl:output standalone='yes'
282                         doc.LoadXml ("<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' ><xsl:output standalone='yes' indent='no'/><xsl:template match='/'><foo/></xsl:template></xsl:transform>");
283                         xslt = new XslTransform ();
284                         xslt.Load (doc, null, null);
285                         reader = xslt.Transform (doc, null, new XmlUrlResolver ());
286                         while (!reader.EOF)
287                                 reader.Read (); // btw no XMLdecl output.
288                 }
289
290                 [Test] // bug #76530
291                 // http://www.w3.org/TR/xslt#section-Creating-Elements-with-xsl:element
292                 // "If the namespace attribute is not present then the QName
293                 // is expanded into an expanded-name using the namespace
294                 // declarations in effect for the xsl:element element,
295                 // including any default namespace declaration."
296                 public void LREDefaultNamespace ()
297                 {
298                         string xsl = @"<xsl:stylesheet version='1.0'
299   xmlns='urn:foo' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
300 <xsl:template match='/*'>
301   <xsl:element name='{local-name()}' />
302 </xsl:template>
303 </xsl:stylesheet>";
304                         string xml = "<root/>";
305                         XslTransform t = new XslTransform ();
306                         t.Load (new XPathDocument (new StringReader (xsl)));
307                         StringWriter sw = new StringWriter ();
308                         XmlTextWriter xw = new XmlTextWriter (sw);
309                         t.Transform (
310                                 new XPathDocument (new StringReader (xml)),
311                                 null, xw);
312                         AssertEquals ("<root xmlns=\"urn:foo\" />",
313                                 sw.ToString ());
314
315                         string xsl2 = @"<xsl:stylesheet version='1.0'
316   xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns='urn:foo'>
317   <xsl:template match='/*'>
318       <root>
319     <xsl:element name='{local-name()}' />
320       </root>
321   </xsl:template>
322 </xsl:stylesheet>";
323                         string xml2 = "<page/>";
324                         t.Load (new XPathDocument (new StringReader (xsl2)));
325                         sw = new StringWriter ();
326                         xw = new XmlTextWriter (sw);
327                         t.Transform (
328                                 new XPathDocument (new StringReader (xml2)),
329                                 null, xw);
330                         AssertEquals ("<root xmlns=\"urn:foo\"><page /></root>",
331                                 sw.ToString ());
332                 }
333         }
334 }