Merge pull request #600 from tr8dr/master
[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
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                         string output = Path.Combine (Path.GetTempPath (), "result.xml");
40                         doc.LoadXml ("<root/>");
41                         xslt.Load ("Test/XmlFiles/xsl/empty.xsl");
42                         xslt.Transform ("Test/XmlFiles/xsl/empty.xsl", output);
43                         result.Load (output);
44                         Assert.AreEqual (2, result.ChildNodes.Count, "count");
45                 }
46
47                 [Test]
48                 [ExpectedException (typeof (XsltCompileException))]
49                 public void InvalidStylesheet ()
50                 {
51                         XmlDocument doc = new XmlDocument ();
52                         doc.LoadXml ("<xsl:element xmlns:xsl='http://www.w3.org/1999/XSL/Transform' />");
53                         XslTransform t = new XslTransform ();
54                         t.Load (doc);
55                 }
56
57                 [Test]
58                 [ExpectedException (typeof (XsltCompileException))]
59                 public void EmptyStylesheet ()
60                 {
61                         XmlDocument doc = new XmlDocument ();
62                         XslTransform t = new XslTransform ();
63                         t.Load (doc);
64                 }
65
66                 [Test]
67                 [ExpectedException (typeof (XsltCompileException))]
68                 public void InvalidStylesheet2 ()
69                 {
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()]
92                 [Category ("NotWorking")] // it depends on "mcs" existence
93                 public void MsxslTest() {
94                         string _styleSheet = @"
95                         <xslt:stylesheet xmlns:xslt=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"" 
96 xmlns:msxsl=""urn:schemas-microsoft-com:xslt"" xmlns:stringutils=""urn:schemas-sourceforge.net-blah"">
97 <xslt:output method=""text"" />
98 <msxsl:script language=""C#"" implements-prefix=""stringutils"">
99         <![CDATA[
100                 string PadRight( string str, int padding) {
101                         return str.PadRight(padding);
102                 }
103         ]]>
104 </msxsl:script>
105 <xslt:template match=""test"">
106         <xslt:value-of select=""stringutils:PadRight(@name, 20)"" />
107 </xslt:template>
108 </xslt:stylesheet>";
109
110                         StringReader stringReader = new StringReader(_styleSheet);
111                         
112                         XslTransform transform = new XslTransform();
113                         XmlTextReader reader = new XmlTextReader(stringReader);
114                         transform.Load(reader, new XmlUrlResolver(), AppDomain.CurrentDomain.Evidence);
115
116                         StringBuilder sb = new StringBuilder();
117                         StringWriter writer = new StringWriter(sb, CultureInfo.InvariantCulture);
118                         XsltArgumentList arguments = new XsltArgumentList();
119
120                         XmlDocument xmlDoc = new XmlDocument();
121                         xmlDoc.LoadXml("<test name=\"test\" />");
122
123                         // Do transformation
124                         transform.Transform(xmlDoc, new XsltArgumentList(), writer, new XmlUrlResolver());
125
126                         Assert.AreEqual ("test".PadRight(20), sb.ToString());
127                 }
128
129                 [Test]
130                 public void MSXslNodeSet ()
131                 {
132                         string xsl = @"<xsl:stylesheet version='1.0' 
133 xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
134 <xsl:template match='/'>
135         <root>
136                 <xsl:variable name='var'>
137                         <xsl:copy-of select='root/foo' />
138                 </xsl:variable>
139                 <xsl:for-each select='msxsl:node-set($var)/foo'>
140                         <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
141                 </xsl:for-each>
142         </root>
143 </xsl:template>
144 </xsl:stylesheet>";
145                         StringWriter sw = new StringWriter ();
146                         XslTransform t = new XslTransform ();
147                         t.Load (new XPathDocument (new StringReader (xsl)));
148                         t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
149                         Assert.AreEqual (@"<?xml version=""1.0"" encoding=""utf-16""?><root xmlns:msxsl=""urn:schemas-microsoft-com:xslt"">foo: Afoo: Bfoo: C</root>", sw.ToString ());
150                 }
151
152                 [Test]
153                 [Category ("NotDotNet")]
154                 // Actually MS.NET here throws XsltException, but Mono returns
155                 // XPathException (since XPath evaluation engine generally
156                 // catches (should catch) static error. It is implementation 
157                 // dependent matter.
158                 [ExpectedException (typeof (XPathException))]
159                 public void MSXslNodeSetRejectsNodeSet ()
160                 {
161                         string xsl = @"<xsl:stylesheet version='1.0' 
162 xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
163 <xsl:template match='/'>
164         <root>
165                 <!-- msxsl:node-set() does not accept a node set -->
166                 <xsl:for-each select='msxsl:node-set(root/foo)'>
167                         <xsl:value-of select='name(.)' />: <xsl:value-of select='@attr' />
168                 </xsl:for-each>
169         </root>
170 </xsl:template>
171 </xsl:stylesheet>";
172                         StringWriter sw = new StringWriter ();
173                         XslTransform t = new XslTransform ();
174                         t.Load (new XPathDocument (new StringReader (xsl)));
175                         t.Transform (new XPathDocument (new XmlTextReader (new StringReader ("<root><foo attr='A'/><foo attr='B'/><foo attr='C'/></root>"))), null, sw);
176                 }
177
178                 [Test]
179                 public void EvaluateEmptyVariableAsBoolean ()
180                 {
181                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
182 <xsl:template match='/'>
183         <xsl:variable name='var'><empty /></xsl:variable>
184         <root><xsl:if test='$var'>true</xsl:if></root>
185 </xsl:template>
186 </xsl:stylesheet>";
187                         XslTransform t = new XslTransform ();
188                         t.Load (new XPathDocument (new StringReader (xsl)));
189                         StringWriter sw = new StringWriter ();
190                         t.Transform (
191                                 new XPathDocument (new StringReader ("<root/>")),
192                                 null,
193                                 sw);
194                         Assert.IsTrue (sw.ToString ().IndexOf ("true") > 0);
195                 }
196
197                 [Test]
198                 [ExpectedException (typeof (XsltCompileException))]
199                 public void NotAllowedPatternAxis ()
200                 {
201                         string xsl = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
202 <xsl:template match='/descendant-or-self::node()/elem'>
203         <ERROR/>
204 </xsl:template>
205 </xsl:stylesheet>";
206                         new XslTransform ().Load (new XPathDocument (
207                                 new StringReader (xsl)));
208                 }
209
210                 [Test]
211                 [ExpectedException (typeof (XsltCompileException))]
212                 public void ImportIncorrectlyLocated ()
213                 {
214                         string xsl = @"<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
215 <xsl:template match='/'></xsl:template>
216         <xsl:import href='dummy.xsl' />
217 </xsl:transform>";
218                         new XslTransform ().Load (new XPathDocument (
219                                 new StringReader (xsl)));
220                 }
221
222                 private WeakReference StylesheetLoad (XslTransform t, string xsl)
223                 {
224                         XPathDocument doc = new XPathDocument (
225                                 new StringReader (xsl));
226                         WeakReference wr = new WeakReference (doc);
227                         t.Load (doc);
228                         return wr;
229                 }
230
231                 private WeakReference StylesheetTransform (XslTransform t, string xml)
232                 {
233                         XPathDocument doc = new XPathDocument (
234                                 new StringReader (xml));
235                         WeakReference wr = new WeakReference (doc);
236                         t.Transform (doc, null, TextWriter.Null, null);
237                         return wr;
238                 }
239
240                 [Test]
241                 // bug #75663.
242                 public void ErrorOnDocumentResolution ()
243                 {
244                         // XslTransform recovers from errors on document resolution.
245                         string xslText = @"<xsl:stylesheet
246                                 xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
247                                 version='1.0'>
248                                 <xsl:variable name='n'
249                                         select='document(""notexist.xml"")' />
250                                 <xsl:template match='/'>xx</xsl:template>
251                                 </xsl:stylesheet>";
252                         string xmlText = @"<root />";
253                         XslTransform transform = new XslTransform ();
254                         XPathDocument doc = new XPathDocument (
255                                 new XmlTextReader ("a.xsl", new StringReader (xslText)));
256                         transform.Load (doc);
257                         XPathDocument xmlDocument = new XPathDocument (new StringReader (xmlText));
258
259                         StringWriter sw = new StringWriter ();
260                         transform.Transform (xmlDocument, null, sw);
261
262                         Assert.AreEqual (
263                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
264                                 "xx", sw.ToString ());
265                 }
266
267                 // bug #76046
268                 [Test]
269                 public void LoadStyleFromNonRoot ()
270                 {
271                         XmlDocument doc = new XmlDocument ();
272                         XslTransform xslt = new XslTransform ();
273                         doc.LoadXml ("<root><dummy /><xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' /></root>");
274                         XmlNode node = doc.ChildNodes [0].ChildNodes [1];
275                         xslt.Load (node, null, null);
276                 }
277
278                 [Test]
279                 public void ReturnEmptyResultsAsXmlReader ()
280                 {
281                         // bug #76115
282                         XmlDocument doc = new XmlDocument ();
283                         doc.LoadXml ("<xsl:transform xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' />");
284                         XslTransform xslt = new XslTransform ();
285                         xslt.Load (doc, null, null);
286                         XmlReader reader = xslt.Transform(doc, null, new XmlUrlResolver ());
287                         reader.Read ();
288
289                         // another case - with xsl:output standalone='yes'
290                         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>");
291                         xslt = new XslTransform ();
292                         xslt.Load (doc, null, null);
293                         reader = xslt.Transform (doc, null, new XmlUrlResolver ());
294                         while (!reader.EOF)
295                                 reader.Read (); // btw no XMLdecl output.
296                 }
297
298                 [Test] // bug #76530
299                 // http://www.w3.org/TR/xslt#section-Creating-Elements-with-xsl:element
300                 // "If the namespace attribute is not present then the QName
301                 // is expanded into an expanded-name using the namespace
302                 // declarations in effect for the xsl:element element,
303                 // including any default namespace declaration."
304                 public void LREDefaultNamespace ()
305                 {
306                         string xsl = @"<xsl:stylesheet version='1.0' xmlns='urn:foo' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
307                                 <xsl:template match='/*'>
308                                         <xsl:element name='{local-name()}' />
309                                 </xsl:template>
310                         </xsl:stylesheet>";
311                         string xml = "<root/>";
312                         XslTransform t = new XslTransform ();
313                         t.Load (new XPathDocument (new StringReader (xsl)));
314                         StringWriter sw = new StringWriter ();
315                         XmlTextWriter xw = new XmlTextWriter (sw);
316                         t.Transform (
317                                 new XPathDocument (new StringReader (xml)),
318                                 null, xw);
319                         Assert.AreEqual ("<root xmlns=\"urn:foo\" />",
320                                 sw.ToString ());
321
322                         string xsl2 = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns='urn:foo'>
323                                 <xsl:template match='/*'>
324                                         <root>
325                                                 <xsl:element name='{local-name()}' />
326                                         </root>
327                                 </xsl:template>
328                         </xsl:stylesheet>";
329                         string xml2 = "<page/>";
330                         t.Load (new XPathDocument (new StringReader (xsl2)));
331                         sw = new StringWriter ();
332                         xw = new XmlTextWriter (sw);
333                         t.Transform (
334                                 new XPathDocument (new StringReader (xml2)),
335                                 null, xw);
336                         Assert.AreEqual ("<root xmlns=\"urn:foo\"><page /></root>",
337                                 sw.ToString ());
338                 }
339
340                 [Test]
341                 // http://lists.ximian.com/pipermail/mono-devel-list/2005-November/015812.html
342                 public void WhitespaceHandling ()
343                 {
344                         string ref_out = @"XML 
345         Extensible Markup language
346          Great stuffs 
347     XSLT  
348         Extensible Markup language
349          Great stuffs 
350     XPATH 
351         Extensible Markup language
352          Great stuffs 
353     XSD 
354         Extensible Markup language
355          Great stuffs 
356     ";
357
358                         XmlDocument d = new XmlDocument ();
359                         d.Load ("Test/XmlFiles/xsl/91834.xml");
360
361                         XslTransform t = new XslTransform ();
362                         t.Load ("Test/XmlFiles/xsl/91834.xsl");
363
364                         StringWriter sw_raw = new StringWriter ();
365                         t.Transform (d, null, sw_raw);
366
367                         Assert.AreEqual (ref_out, sw_raw.ToString ().Replace ("\r\n", "\n"));
368                 }
369
370                 // http://support.microsoft.com/default.aspx?scid=kb;en-us;829014
371                 [Test]
372                 public void EmptyNodeSetSort ()
373                 {
374                         string xmlFragment = @"<?xml version=""1.0"" encoding=""utf-8""?>
375                                 <EMPLOYEES>
376                                         <EMPLOYEE>
377                                                 <NAME>Steve</NAME>
378                                                 <DEPT>IT</DEPT>
379                                                 <SKILL>C++</SKILL>
380                                                 <SKILL>C#</SKILL>
381                                         </EMPLOYEE>
382                                         <EMPLOYEE>
383                                                 <NAME>John</NAME>
384                                                 <DEPT>IT</DEPT>
385                                                 <SKILL>VB.NET</SKILL>
386                                                 <SKILL>SQl Server</SKILL>
387                                         </EMPLOYEE>
388                                 </EMPLOYEES>";
389
390                         string xsltFragment = @"<?xml version=""1.0""?>
391                                 <xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
392                                         <xsl:output omit-xml-declaration=""yes"" />
393                                         <xsl:preserve-space elements=""*"" />
394                                         <xsl:template match=""/EMPLOYEES"">
395                                                 <xsl:for-each select=""EMPLOYEE[DEPT='Finance']"">
396                                                         <xsl:sort select=""NAME""/>
397                                                         <xsl:value-of select=""NAME""/>
398                                                 </xsl:for-each>
399                                         </xsl:template>
400                                 </xsl:stylesheet>";
401
402                         XmlTextReader xmlRdr = new XmlTextReader (new StringReader (xmlFragment));
403                         XmlTextReader xsltRdr = new XmlTextReader (new StringReader (xsltFragment));
404
405                         XslTransform stylesheet = new XslTransform ();
406                         stylesheet.Load (xsltRdr, new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
407
408                         StringWriter sw = new StringWriter ();
409
410                         stylesheet.Transform (new XPathDocument (xmlRdr), new XsltArgumentList (),
411                                 sw, new XmlUrlResolver ());
412
413                         Assert.AreEqual (0, sw.ToString ().Length);
414                 }
415
416                 // http://support.microsoft.com/default.aspx?scid=kb;en-us;834667
417                 [Test]
418                 [Category ("NotDotNet")]
419                 public void LocalParameter ()
420                 {
421                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
422                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
423                                         <xsl:param name=""param1"" select=""'global-param1-default'"" />
424                                         <xsl:param name=""param2"" select=""'global-param2-default'"" />
425                                         <xsl:output method=""text"" encoding=""ascii"" />
426                                         <xsl:template match=""/"">
427                                                 <xsl:call-template name=""Test"">
428                                                         <xsl:with-param name=""param1"" select=""'local-param1-arg'"" />
429                                                         <xsl:with-param name=""param2"" select=""'local-param2-arg'"" />
430                                                 </xsl:call-template>
431                                         </xsl:template>
432                                         <xsl:template name=""Test"">
433                                                 <xsl:param name=""param1"" select=""'local-param1-default'"" />
434                                                 <xsl:param name=""param2"" select=""'local-param2-default'"" />
435                                                 <xsl:value-of select=""$param1"" /><xsl:text>/</xsl:text><xsl:value-of select=""$param2"" />
436                                         </xsl:template>
437                                 </xsl:stylesheet>";
438
439                         XmlDocument xmlDoc = new XmlDocument ();
440                         xmlDoc.LoadXml ("<dummy />");
441
442                         XslTransform xsltProcessor = new XslTransform ();
443                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
444                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
445
446                         StringWriter sw = new StringWriter ();
447
448                         XsltArgumentList xsltArgs = new XsltArgumentList ();
449                         xsltArgs.AddParam ("param1", string.Empty, "global-param1-arg");
450                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
451
452                         Assert.AreEqual ("local-param1-arg/local-param2-arg", sw.ToString ());
453                 }
454
455                 [Test]
456                 public void Output_Standalone ()
457                 {
458                         StringWriter sw = null;
459                         XsltArgumentList xsltArgs = new XsltArgumentList ();
460                         XslTransform xsltProcessor = new XslTransform ();
461
462                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
463                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
464                                         <xsl:output {0} />
465                                         <xsl:template match=""/"">
466                                                 <root />
467                                         </xsl:template>
468                                 </xsl:stylesheet>";
469
470                         XmlDocument xmlDoc = new XmlDocument ();
471                         xmlDoc.LoadXml ("<dummy />");
472
473                         sw = new StringWriter ();
474                         xsltProcessor.Load (new XmlTextReader (new StringReader (
475                                 string.Format(xsltFragment, "standalone=\"yes\""))), 
476                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
477                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
478
479                         Assert.AreEqual (
480                                 "<?xml version=\"1.0\" encoding=\"utf-16\"" +
481                                 " standalone=\"yes\"?><root />", sw.ToString (), "#1");
482
483                         sw = new StringWriter ();
484                         xsltProcessor.Load (new XmlTextReader (new StringReader (
485                                 string.Format (xsltFragment, "standalone=\"no\""))),
486                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
487                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
488
489                         Assert.AreEqual (
490                                 "<?xml version=\"1.0\" encoding=\"utf-16\"" +
491                                 " standalone=\"no\"?><root />", sw.ToString (), "#2");
492
493                         sw = new StringWriter ();
494                         xsltProcessor.Load (new XmlTextReader (new StringReader (
495                                 string.Format (xsltFragment, ""))),
496                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
497                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
498
499                         Assert.AreEqual (
500                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
501                                 "<root />", sw.ToString (), "#3");
502                 }
503
504                 [Test]
505                 [ExpectedException (typeof (XsltCompileException))]
506                 public void Output_Standalone_Invalid ()
507                 {
508                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
509                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
510                                         <xsl:output standalone=""Yes"" />
511                                 </xsl:stylesheet>";
512                         XslTransform xsltProcessor = new XslTransform ();
513                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
514                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
515                 }
516
517                 [Test]
518                 public void Output_Standalone_ForwardsCompatible ()
519                 {
520                         StringWriter sw = new StringWriter ();
521                         XsltArgumentList xsltArgs = new XsltArgumentList ();
522                         XslTransform xsltProcessor = new XslTransform ();
523                         XmlDocument xmlDoc = new XmlDocument ();
524                         xmlDoc.LoadXml ("<dummy />");
525
526                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
527                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.5"">
528                                         <xsl:output standalone=""{0}"" />
529                                         <xsl:template match=""/"">
530                                                 <root />
531                                         </xsl:template>
532                                 </xsl:stylesheet>";
533
534                         // standalone is "Yes"
535                         xsltProcessor.Load (new XmlTextReader (new StringReader (
536                                 string.Format (xsltFragment, "Yes"))),
537                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
538                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
539
540                         Assert.AreEqual (
541                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
542                                 "<root />", sw.ToString (), "#1");
543
544                         // standalone is empty
545                         sw.GetStringBuilder ().Length = 0;
546                         xsltProcessor.Load (new XmlTextReader (new StringReader (
547                                 string.Format (xsltFragment, ""))),
548                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
549                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
550
551                         Assert.AreEqual (
552                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
553                                 "<root />", sw.ToString (), "#2");
554                 }
555
556                 [Test]
557                 [ExpectedException (typeof (XsltCompileException))]
558                 public void Output_Standalone_Empty ()
559                 {
560                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
561                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
562                                         <xsl:output standalone="""" />
563                                 </xsl:stylesheet>";
564                         XslTransform xsltProcessor = new XslTransform ();
565                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
566                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
567                 }
568
569                 [Test]
570                 public void Output_OmitXmlDeclaration ()
571                 {
572                         StringWriter sw = null;
573                         XsltArgumentList xsltArgs = new XsltArgumentList ();
574                         XslTransform xsltProcessor = new XslTransform ();
575
576                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
577                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
578                                         <xsl:output {0} />
579                                         <xsl:template match=""/"">
580                                                 <root />
581                                         </xsl:template>
582                                 </xsl:stylesheet>";
583
584                         XmlDocument xmlDoc = new XmlDocument ();
585                         xmlDoc.LoadXml ("<dummy />");
586
587                         sw = new StringWriter ();
588                         xsltProcessor.Load (new XmlTextReader (new StringReader (
589                                 string.Format (xsltFragment, "omit-xml-declaration=\"yes\""))),
590                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
591                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
592
593                         Assert.AreEqual ("<root />", sw.ToString (), "#1");
594
595                         sw.GetStringBuilder ().Length = 0;
596                         xsltProcessor.Load (new XmlTextReader (new StringReader (
597                                 string.Format (xsltFragment, "omit-xml-declaration=\"no\""))),
598                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
599                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
600
601                         Assert.AreEqual (
602                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
603                                 "<root />", sw.ToString (), "#2");
604                 }
605
606                 [Test]
607                 [ExpectedException (typeof (XsltCompileException))]
608                 public void Output_OmitXmlDeclaration_Invalid ()
609                 {
610                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
611                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
612                                         <xsl:output omit-xml-declaration=""Yes"" />
613                                 </xsl:stylesheet>";
614                         XslTransform xsltProcessor = new XslTransform ();
615                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
616                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
617                 }
618
619                 [Test]
620                 [ExpectedException (typeof (XsltCompileException))]
621                 public void Output_OmitXmlDeclaration_Empty ()
622                 {
623                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
624                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
625                                         <xsl:output omit-xml-declaration="""" />
626                                 </xsl:stylesheet>";
627                         XslTransform xsltProcessor = new XslTransform ();
628                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
629                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
630                 }
631
632                 [Test]
633                 public void Output_OmitXmlDeclaration_ForwardsCompatible ()
634                 {
635                         StringWriter sw = new StringWriter ();
636                         XsltArgumentList xsltArgs = new XsltArgumentList ();
637                         XslTransform xsltProcessor = new XslTransform ();
638                         XmlDocument xmlDoc = new XmlDocument ();
639                         xmlDoc.LoadXml ("<dummy />");
640
641                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
642                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.5"">
643                                         <xsl:output omit-xml-declaration=""{0}"" />
644                                         <xsl:template match=""/"">
645                                                 <root />
646                                         </xsl:template>
647                                 </xsl:stylesheet>";
648
649                         // omit-xml-declaration is "Yes"
650                         xsltProcessor.Load (new XmlTextReader (new StringReader (
651                                 string.Format (xsltFragment, "Yes"))),
652                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
653                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
654
655                         Assert.AreEqual (
656                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
657                                 "<root />", sw.ToString (), "#1");
658
659                         // omit-xml-declaration is empty
660                         sw.GetStringBuilder ().Length = 0;
661                         xsltProcessor.Load (new XmlTextReader (new StringReader (
662                                 string.Format (xsltFragment, ""))),
663                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
664                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
665
666                         Assert.AreEqual (
667                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
668                                 "<root />", sw.ToString (), "#2");
669                 }
670
671                 [Test]
672                 public void Output_DocType_Xml ()
673                 {
674                         XsltArgumentList xsltArgs = new XsltArgumentList ();
675                         XslTransform xsltProcessor = new XslTransform ();
676
677                         // set both doctype-system and doctype-public
678                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
679                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
680                                         <xsl:output 
681                                                 doctype-public=""-//W3C//DTD XHTML 1.0 Strict//EN"" 
682                                                 doctype-system=""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"" />
683                                         <xsl:template match=""/"">
684                                                 <xsl:element name=""test"">
685                                                         <xsl:element name=""abc"" />
686                                                 </xsl:element>
687                                         </xsl:template>
688                                 </xsl:stylesheet>";
689
690                         XmlDocument xmlDoc = new XmlDocument ();
691                         xmlDoc.LoadXml ("<dummy />");
692
693                         StringWriter sw = new StringWriter ();
694                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
695                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
696                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
697
698                         Assert.AreEqual (
699                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
700                                 "<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
701                                 "<test><abc /></test>", sw.ToString (), "#1");
702
703                         // only set doctype-public
704                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
705                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
706                                         <xsl:output
707                                                 doctype-public=""-//W3C//DTD XHTML 1.0 Strict//EN"" />
708                                         <xsl:template match=""/"">
709                                                 <xsl:element name=""test"">
710                                                         <xsl:element name=""abc"" />
711                                                 </xsl:element>
712                                         </xsl:template>
713                                 </xsl:stylesheet>";
714
715                         sw.GetStringBuilder ().Length = 0;
716                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
717                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
718                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
719
720                         Assert.AreEqual (
721                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
722                                 "<test><abc /></test>", sw.ToString (), "#2");
723
724                         // only set doctype-system
725                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
726                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
727                                         <xsl:output
728                                                 indent=""no""
729                                                 doctype-system=""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"" />
730                                         <xsl:template match=""/"">
731                                                 <xsl:element name=""test"">
732                                                         <xsl:element name=""abc"" />
733                                                 </xsl:element>
734                                         </xsl:template>
735                                 </xsl:stylesheet>";
736
737                         sw.GetStringBuilder ().Length = 0;
738                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
739                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
740                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
741
742                         Assert.AreEqual (
743                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
744                                 "<!DOCTYPE test SYSTEM \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
745                                 "<test><abc /></test>", sw.ToString (), "#3");
746
747                         // set empty doctype-public and empty doctype-system
748                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
749                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
750                                         <xsl:output
751                                                 doctype-public=""""
752                                                 doctype-system="""" />
753                                         <xsl:template match=""/"">
754                                                 <xsl:element name=""test"">
755                                                         <xsl:element name=""abc"" />
756                                                 </xsl:element>
757                                         </xsl:template>
758                                 </xsl:stylesheet>";
759
760                         sw.GetStringBuilder ().Length = 0;
761                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
762                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
763                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
764
765                         Assert.AreEqual (
766                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
767                                 "<!DOCTYPE test PUBLIC \"\" \"\">" +
768                                 "<test><abc /></test>", sw.ToString (), "#4");
769
770                         // set empty doctype-public
771                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
772                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
773                                         <xsl:output
774                                                 indent=""no""
775                                                 doctype-public="""" />
776                                         <xsl:template match=""/"">
777                                                 <xsl:element name=""test"">
778                                                         <xsl:element name=""abc"" />
779                                                 </xsl:element>
780                                         </xsl:template>
781                                 </xsl:stylesheet>";
782
783                         sw.GetStringBuilder ().Length = 0;
784                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
785                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
786                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
787
788                         Assert.AreEqual (
789                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
790                                 "<test><abc /></test>", sw.ToString (), "#5");
791
792                         // set empty doctype-system
793                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
794                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
795                                         <xsl:output
796                                                 doctype-system="""" />
797                                         <xsl:template match=""/"">
798                                                 <xsl:element name=""test"">
799                                                         <xsl:element name=""abc"" />
800                                                 </xsl:element>
801                                         </xsl:template>
802                                 </xsl:stylesheet>";
803
804                         sw.GetStringBuilder ().Length = 0;
805                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
806                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
807                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
808
809                         Assert.AreEqual (
810                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
811                                 "<!DOCTYPE test SYSTEM \"\">" +
812                                 "<test><abc /></test>", sw.ToString (), "#6");
813                 }
814
815                 [Test]
816                 public void Output_DocType_Html ()
817                 {
818                         XsltArgumentList xsltArgs = new XsltArgumentList ();
819                         XslTransform xsltProcessor = new XslTransform ();
820
821                         // set both doctype-system and doctype-public
822                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
823                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
824                                         <xsl:output 
825                                                 method=""html""
826                                                 indent=""no""
827                                                 doctype-public=""-//W3C//DTD XHTML 1.0 Strict//EN"" 
828                                                 doctype-system=""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"" />
829                                         <xsl:template match=""/"">
830                                                 <xsl:element name=""test"">
831                                                         <xsl:element name=""abc"" />
832                                                 </xsl:element>
833                                         </xsl:template>
834                                 </xsl:stylesheet>";
835
836                         XmlDocument xmlDoc = new XmlDocument ();
837                         xmlDoc.LoadXml ("<dummy />");
838
839                         StringWriter sw = new StringWriter ();
840                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
841                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
842                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
843
844                         Assert.AreEqual (
845                                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
846                                 "<test><abc></abc></test>", sw.ToString (), "#1");
847
848                         // only set doctype-public
849                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
850                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
851                                         <xsl:output 
852                                                 method=""html""
853                                                 indent=""no""
854                                                 doctype-public=""-//W3C//DTD XHTML 1.0 Strict//EN"" />
855                                         <xsl:template match=""/"">
856                                                 <xsl:element name=""test"">
857                                                         <xsl:element name=""abc"" />
858                                                 </xsl:element>
859                                         </xsl:template>
860                                 </xsl:stylesheet>";
861
862                         sw.GetStringBuilder ().Length = 0;
863                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
864                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
865                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
866
867                         Assert.AreEqual (
868                                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" >" +
869                                 "<test><abc></abc></test>", sw.ToString (), "#2");
870
871                         // only set doctype-system
872                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
873                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
874                                         <xsl:output 
875                                                 method=""html""
876                                                 indent=""no""
877                                                 doctype-system=""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"" />
878                                         <xsl:template match=""/"">
879                                                 <xsl:element name=""test"">
880                                                         <xsl:element name=""abc"" />
881                                                 </xsl:element>
882                                         </xsl:template>
883                                 </xsl:stylesheet>";
884
885                         sw.GetStringBuilder ().Length = 0;
886                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
887                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
888                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
889
890                         Assert.AreEqual (
891                                 "<!DOCTYPE html SYSTEM \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
892                                 "<test><abc></abc></test>", sw.ToString (), "#3");
893
894                         // set empty doctype-public and empty doctype-system
895                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
896                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
897                                         <xsl:output
898                                                 method=""html""
899                                                 indent=""no""
900                                                 doctype-public="""" doctype-system="""" />
901                                         <xsl:template match=""/"">
902                                                 <xsl:element name=""test"">
903                                                         <xsl:element name=""abc"" />
904                                                 </xsl:element>
905                                         </xsl:template>
906                                 </xsl:stylesheet>";
907
908                         sw.GetStringBuilder ().Length = 0;
909                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
910                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
911                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
912
913                         Assert.AreEqual (
914                                 "<!DOCTYPE html PUBLIC \"\" \"\">" +
915                                 "<test><abc></abc></test>", sw.ToString (), "#4");
916
917                         // set empty doctype-public
918                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
919                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
920                                         <xsl:output
921                                                 method=""html""
922                                                 indent=""no""
923                                                 doctype-public="""" />
924                                         <xsl:template match=""/"">
925                                                 <xsl:element name=""test"">
926                                                         <xsl:element name=""abc"" />
927                                                 </xsl:element>
928                                         </xsl:template>
929                                 </xsl:stylesheet>";
930
931                         sw.GetStringBuilder ().Length = 0;
932                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
933                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
934                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
935
936                         Assert.AreEqual (
937                                 "<!DOCTYPE html PUBLIC \"\" >" +
938                                 "<test><abc></abc></test>", sw.ToString (), "#5");
939
940                         // set empty doctype-system
941                         xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
942                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
943                                         <xsl:output
944                                                 method=""html""
945                                                 indent=""no""
946                                                 doctype-system="""" />
947                                         <xsl:template match=""/"">
948                                                 <xsl:element name=""test"">
949                                                         <xsl:element name=""abc"" />
950                                                 </xsl:element>
951                                         </xsl:template>
952                                 </xsl:stylesheet>";
953
954                         sw.GetStringBuilder ().Length = 0;
955                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
956                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
957                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
958
959                         Assert.AreEqual (
960                                 "<!DOCTYPE html SYSTEM \"\">" +
961                                 "<test><abc></abc></test>", sw.ToString (), "#6");
962                 }
963
964                 [Test]
965                 public void Output_Indent_Xml_DocType ()
966                 {
967                         XsltArgumentList xsltArgs = new XsltArgumentList ();
968                         XslTransform xsltProcessor = new XslTransform ();
969
970                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
971                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
972                                         <xsl:output
973                                                 doctype-public=""-//W3C//DTD XHTML 1.0 Strict//EN""
974                                                 doctype-system=""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd""
975                                                 {0} />
976                                         <xsl:template match=""/"">
977                                                 <xsl:element name=""test"">
978                                                         <xsl:element name=""something"">
979                                                                 <xsl:element name=""else"" />
980                                                         </xsl:element>
981                                                 </xsl:element>
982                                         </xsl:template>
983                                 </xsl:stylesheet>";
984
985                         XmlDocument xmlDoc = new XmlDocument ();
986                         xmlDoc.LoadXml ("<dummy />");
987
988                         // set indent to yes
989                         StringWriter sw = new StringWriter ();
990                         xsltProcessor.Load (new XmlTextReader (new StringReader (
991                                 string.Format (xsltFragment, "indent=\"yes\""))),
992                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
993                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
994
995                         Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
996                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>{0}" +
997                                 "<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">{0}" +
998                                 "<test>{0}" +
999                                 "  <something>{0}" +
1000                                 "    <else />{0}" +
1001                                 "  </something>{0}" +
1002                                 "</test>", Environment.NewLine), sw.ToString (), "#1");
1003
1004                         // set indent to no
1005                         sw.GetStringBuilder ().Length = 0;
1006                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1007                                 string.Format (xsltFragment, "indent=\"no\""))),
1008                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1009                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1010
1011                         Assert.AreEqual (
1012                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1013                                 "<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
1014                                 "<test><something><else /></something></test>", sw.ToString (),
1015                                 "#2");
1016
1017                         // indent not set
1018                         sw.GetStringBuilder ().Length = 0;
1019                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1020                                 string.Format (xsltFragment, ""))),
1021                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1022                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1023
1024                         Assert.AreEqual (
1025                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1026                                 "<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
1027                                 "<test><something><else /></something></test>", sw.ToString (),
1028                                 "#3");
1029                 }
1030
1031                 [Test]
1032                 [Category ("NotWorking")] // bug #77081: mono does not output newline and indentation for non-html elements
1033                 public void Output_Indent_Html_DocType ()
1034                 {
1035                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1036                         XslTransform xsltProcessor = new XslTransform ();
1037
1038                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1039                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1040                                         <xsl:output
1041                                                 method=""html""
1042                                                 doctype-public=""-//W3C//DTD XHTML 1.0 Strict//EN""
1043                                                 doctype-system=""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd""
1044                                                 {0} />
1045                                         <xsl:template match=""/"">
1046                                                 <xsl:element name=""test"">
1047                                                         <xsl:element name=""something"">
1048                                                                 <xsl:element name=""else"" />
1049                                                         </xsl:element>
1050                                                 </xsl:element>
1051                                         </xsl:template>
1052                                 </xsl:stylesheet>";
1053
1054                         XmlDocument xmlDoc = new XmlDocument ();
1055                         xmlDoc.LoadXml ("<dummy />");
1056
1057                         // set indent to yes
1058                         StringWriter sw = new StringWriter ();
1059                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1060                                 string.Format (xsltFragment, "indent=\"yes\""))),
1061                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1062                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1063
1064                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1065                                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">{0}" +
1066                                 "<test>{0}" +
1067                                 "  <something>{0}" +
1068                                 "    <else>{0}" +
1069                                 "    </else>{0}" +
1070                                 "  </something>{0}" +
1071                                 "</test>", Environment.NewLine), sw.ToString (), "#1");
1072
1073                         // set indent to no
1074                         sw.GetStringBuilder ().Length = 0;
1075                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1076                                 string.Format (xsltFragment, "indent=\"no\""))),
1077                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1078                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1079
1080                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1081                                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +
1082                                 "<test><something><else></else></something></test>",
1083                                 Environment.NewLine), sw.ToString (), "#2");
1084
1085                         // indent not set
1086                         sw.GetStringBuilder ().Length = 0;
1087                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1088                                 string.Format (xsltFragment, ""))),
1089                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1090                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1091
1092                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1093                                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">{0}" +
1094                                 "<test>{0}" +
1095                                 "  <something>{0}" +
1096                                 "    <else>{0}" +
1097                                 "    </else>{0}" +
1098                                 "  </something>{0}" +
1099                                 "</test>", Environment.NewLine), sw.ToString (), "#3");
1100                 }
1101
1102                 [Test]
1103                 public void Output_Indent_Xml ()
1104                 {
1105                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1106                         XslTransform xsltProcessor = new XslTransform ();
1107
1108                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1109                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1110                                         <xsl:output
1111                                                 {0} />
1112                                         <xsl:template match=""/"">
1113                                                 <xsl:element name=""test"">
1114                                                         <xsl:element name=""something"">
1115                                                                 <xsl:element name=""else"" />
1116                                                         </xsl:element>
1117                                                 </xsl:element>
1118                                         </xsl:template>
1119                                 </xsl:stylesheet>";
1120
1121                         XmlDocument xmlDoc = new XmlDocument ();
1122                         xmlDoc.LoadXml ("<dummy />");
1123
1124                         // set indent to yes
1125                         StringWriter sw = new StringWriter ();
1126                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1127                                 string.Format (xsltFragment, "indent=\"yes\""))),
1128                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1129                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1130
1131                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1132                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>{0}" +
1133                                 "<test>{0}" +
1134                                 "  <something>{0}" +
1135                                 "    <else />{0}" +
1136                                 "  </something>{0}" +
1137                                 "</test>", Environment.NewLine), sw.ToString (), "#1");
1138
1139                         // set indent to no
1140                         sw.GetStringBuilder ().Length = 0;
1141                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1142                                 string.Format (xsltFragment, "indent=\"no\""))),
1143                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1144                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1145
1146                         Assert.AreEqual (
1147                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1148                                 "<test><something><else /></something></test>", sw.ToString (),
1149                                 "#2");
1150
1151                         // indent not set
1152                         sw.GetStringBuilder ().Length = 0;
1153                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1154                                 string.Format (xsltFragment, ""))),
1155                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1156                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1157
1158                         Assert.AreEqual (
1159                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1160                                 "<test><something><else /></something></test>", sw.ToString (),
1161                                 "#3");
1162                 }
1163
1164                 [Test]
1165                 [Category ("NotWorking")] // bug #77081: mono does not output newline and indentation for non-html elements
1166                 public void Output_Indent_Html ()
1167                 {
1168                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1169                         XslTransform xsltProcessor = new XslTransform ();
1170
1171                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1172                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1173                                         <xsl:output
1174                                                 method=""html""
1175                                                 {0} />
1176                                         <xsl:template match=""/"">
1177                                                 <xsl:element name=""html"">
1178                                                         <xsl:element name=""body"">
1179                                                                 <xsl:element name=""p"" />
1180                                                                 <xsl:element name=""p"">
1181                                                                         <xsl:text>something</xsl:text>
1182                                                                 </xsl:element>
1183                                                                 <xsl:element name=""p"">
1184                                                                         <xsl:element name=""div"" />
1185                                                                 </xsl:element>
1186                                                                 <xsl:element name=""p"">
1187                                                                         <xsl:element name=""whatever"" />
1188                                                                 </xsl:element>
1189                                                         </xsl:element>
1190                                                 </xsl:element>
1191                                         </xsl:template>
1192                                 </xsl:stylesheet>";
1193
1194                         XmlDocument xmlDoc = new XmlDocument ();
1195                         xmlDoc.LoadXml ("<dummy />");
1196
1197                         // set indent to yes
1198                         StringWriter sw = new StringWriter ();
1199                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1200                                 string.Format (xsltFragment, "indent=\"yes\""))),
1201                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1202                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1203
1204                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1205                                 "<html>{0}" +
1206                                 "  <body>{0}" +
1207                                 "    <p>{0}" +
1208                                 "    </p>{0}" +
1209                                 "    <p>something</p>{0}" +
1210                                 "    <p>{0}" +
1211                                 "      <div>{0}" +
1212                                 "      </div>{0}" +
1213                                 "    </p>{0}" +
1214                                 "    <p>{0}" +
1215                                 "      <whatever>{0}" +
1216                                 "      </whatever>{0}" +
1217                                 "    </p>{0}" +
1218                                 "  </body>{0}" +
1219                                 "</html>", Environment.NewLine), sw.ToString (), "#1");
1220
1221                         // set indent to no
1222                         sw.GetStringBuilder ().Length = 0;
1223                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1224                                 string.Format (xsltFragment, "indent=\"no\""))),
1225                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1226                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1227
1228                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1229                                 "<html><body><p></p><p>something</p><p><div></div></p>" +
1230                                 "<p><whatever></whatever></p></body></html>",
1231                                 Environment.NewLine), sw.ToString (), "#2");
1232
1233                         // indent not set
1234                         sw.GetStringBuilder ().Length = 0;
1235                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1236                                 string.Format (xsltFragment, ""))),
1237                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1238                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1239
1240                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1241                                 "<html>{0}" +
1242                                 "  <body>{0}" +
1243                                 "    <p>{0}" +
1244                                 "    </p>{0}" +
1245                                 "    <p>something</p>{0}" +
1246                                 "    <p>{0}" +
1247                                 "      <div>{0}" +
1248                                 "      </div>{0}" +
1249                                 "    </p>{0}" +
1250                                 "    <p>{0}" +
1251                                 "      <whatever>{0}" +
1252                                 "      </whatever>{0}" +
1253                                 "    </p>{0}" +
1254                                 "  </body>{0}" +
1255                                 "</html>", Environment.NewLine), sw.ToString (), "#3");
1256                 }
1257
1258                 [Test]
1259                 [ExpectedException (typeof (XsltCompileException))]
1260                 public void Output_Indent_Invalid ()
1261                 {
1262                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1263                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1264                                         <xsl:output indent=""Yes"" />
1265                                 </xsl:stylesheet>";
1266                         XslTransform xsltProcessor = new XslTransform ();
1267                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1268                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1269                 }
1270
1271                 [Test]
1272                 [ExpectedException (typeof (XsltCompileException))]
1273                 public void Output_Indent_Empty ()
1274                 {
1275                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1276                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1277                                         <xsl:output indent="""" />
1278                                 </xsl:stylesheet>";
1279                         XslTransform xsltProcessor = new XslTransform ();
1280                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1281                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1282                 }
1283
1284                 [Test]
1285                 public void Output_Indent_ForwardsCompatible ()
1286                 {
1287                         StringWriter sw = new StringWriter ();
1288                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1289                         XslTransform xsltProcessor = new XslTransform ();
1290                         XmlDocument xmlDoc = new XmlDocument ();
1291                         xmlDoc.LoadXml ("<dummy />");
1292
1293                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1294                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.5"">
1295                                         <xsl:output indent=""{0}"" />
1296                                         <xsl:template match=""/"">
1297                                                 <root />
1298                                         </xsl:template>
1299                                 </xsl:stylesheet>";
1300
1301                         // indent is "Yes"
1302                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1303                                 string.Format (xsltFragment, "Yes"))),
1304                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1305                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1306
1307                         Assert.AreEqual (
1308                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1309                                 "<root />", sw.ToString (), "#1");
1310
1311                         // indent is empty
1312                         sw.GetStringBuilder ().Length = 0;
1313                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1314                                 string.Format (xsltFragment, ""))),
1315                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1316                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1317
1318                         Assert.AreEqual (
1319                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1320                                 "<root />", sw.ToString (), "#2");
1321                 }
1322
1323                 [Test]
1324                 public void Output_MediaType ()
1325                 {
1326                         StringWriter sw = null;
1327                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1328                         XslTransform xsltProcessor = new XslTransform ();
1329
1330                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1331                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1332                                         <xsl:output media-type=""whatever"" />
1333                                         <xsl:template match=""/"">
1334                                                 <root />
1335                                         </xsl:template>
1336                                 </xsl:stylesheet>";
1337
1338                         XmlDocument xmlDoc = new XmlDocument ();
1339                         xmlDoc.LoadXml ("<dummy />");
1340
1341                         sw = new StringWriter ();
1342                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1343                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1344                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1345
1346                         Assert.AreEqual (
1347                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1348                                 "<root />", sw.ToString ());
1349                 }
1350
1351                 [Test]
1352                 public void Output_Encoding_TextWriter ()
1353                 {
1354                         StringWriter sw = null;
1355                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1356                         XslTransform xsltProcessor = new XslTransform ();
1357
1358                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1359                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1360                                         <xsl:output {0} />
1361                                         <xsl:template match=""/"">
1362                                                 <root />
1363                                         </xsl:template>
1364                                 </xsl:stylesheet>";
1365
1366                         XmlDocument xmlDoc = new XmlDocument ();
1367                         xmlDoc.LoadXml ("<dummy />");
1368
1369                         // no encoding
1370                         sw = new StringWriter ();
1371                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1372                                 string.Format (xsltFragment, string.Empty))),
1373                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1374                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1375
1376                         Assert.AreEqual (
1377                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1378                                 "<root />", sw.ToString (), "#1");
1379
1380                         // valid encoding
1381                         sw.GetStringBuilder ().Length = 0;
1382                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1383                                 string.Format(xsltFragment, "encoding=\"iso-8859-1\""))),
1384                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1385                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1386
1387                         Assert.AreEqual (
1388                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1389                                 "<root />", sw.ToString (), "#1");
1390
1391                         // invalid encoding
1392                         sw.GetStringBuilder ().Length = 0;
1393                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1394                                 string.Format (xsltFragment, "encoding=\"doesnotexist\""))),
1395                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1396                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1397
1398                         Assert.AreEqual (
1399                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1400                                 "<root />", sw.ToString (), "#2");
1401
1402                         // empty encoding
1403                         sw.GetStringBuilder ().Length = 0;
1404                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1405                                 string.Format (xsltFragment, "encoding=\"\""))),
1406                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1407                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1408
1409                         Assert.AreEqual (
1410                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1411                                 "<root />", sw.ToString (), "#3");
1412                 }
1413
1414                 [Test]
1415                 public void Output_Encoding_Stream ()
1416                 {
1417                         MemoryStream ms = null;
1418                         string result = null;
1419                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1420                         XslTransform xsltProcessor = new XslTransform ();
1421
1422                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1423                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1424                                         <xsl:output {0} />
1425                                         <xsl:template match=""/"">
1426                                                 <root />
1427                                         </xsl:template>
1428                                 </xsl:stylesheet>";
1429
1430                         XmlDocument xmlDoc = new XmlDocument ();
1431                         xmlDoc.LoadXml ("<dummy />");
1432
1433                         // no encoding
1434                         ms = new MemoryStream ();
1435                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1436                                 string.Format (xsltFragment, string.Empty))),
1437                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1438                         xsltProcessor.Transform (xmlDoc, xsltArgs, ms, new XmlUrlResolver ());
1439                         ms.Position = 0;
1440                         using (StreamReader sr = new StreamReader (ms, true)) {
1441                                 result = sr.ReadToEnd ();
1442                         }
1443
1444                         Assert.AreEqual (
1445                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1446                                 "<root />", result, "#1");
1447
1448                         // valid encoding
1449                         ms = new MemoryStream ();
1450                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1451                                 string.Format (xsltFragment, "encoding=\"iso-8859-1\""))),
1452                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1453                         xsltProcessor.Transform (xmlDoc, xsltArgs, ms, new XmlUrlResolver ());
1454                         ms.Position = 0;
1455                         using (StreamReader sr = new StreamReader (ms, true)) {
1456                                 result = sr.ReadToEnd ();
1457                         }
1458
1459                         Assert.AreEqual (
1460                                 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>" +
1461                                 "<root />", result, "#2");
1462
1463                         // invalid encoding
1464                         ms = new MemoryStream ();
1465                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1466                                 string.Format (xsltFragment, "encoding=\"doesnotexist\""))),
1467                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1468                         xsltProcessor.Transform (xmlDoc, xsltArgs, ms, new XmlUrlResolver ());
1469                         ms.Position = 0;
1470                         using (StreamReader sr = new StreamReader (ms, true)) {
1471                                 result = sr.ReadToEnd ();
1472                         }
1473
1474                         Assert.AreEqual (
1475                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1476                                 "<root />", result, "#3");
1477
1478                         // empty encoding
1479                         ms = new MemoryStream ();
1480                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1481                                 string.Format (xsltFragment, "encoding=\"\""))),
1482                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1483                         xsltProcessor.Transform (xmlDoc, xsltArgs, ms, new XmlUrlResolver ());
1484                         ms.Position = 0;
1485                         using (StreamReader sr = new StreamReader (ms, true)) {
1486                                 result = sr.ReadToEnd ();
1487                         }
1488
1489                         Assert.AreEqual (
1490                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1491                                 "<root />", result, "#4");
1492                 }
1493
1494                 [Test]
1495                 public void Output_Version ()
1496                 {
1497                         StringWriter sw = null;
1498                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1499                         XslTransform xsltProcessor = new XslTransform ();
1500
1501                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1502                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1503                                         <xsl:output version=""{0}"" />
1504                                         <xsl:template match=""/"">
1505                                                 <root />
1506                                         </xsl:template>
1507                                 </xsl:stylesheet>";
1508
1509                         XmlDocument xmlDoc = new XmlDocument ();
1510                         xmlDoc.LoadXml ("<dummy />");
1511
1512                         // version 1.0
1513                         sw = new StringWriter ();
1514                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1515                                 string.Format (xsltFragment, "1.0"))),
1516                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1517                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1518
1519                         Assert.AreEqual (
1520                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1521                                 "<root />", sw.ToString (), "#1");
1522
1523                         // version 2.0
1524                         sw.GetStringBuilder ().Length = 0;
1525                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1526                                 string.Format (xsltFragment, "2.0"))),
1527                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1528                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1529
1530                         Assert.AreEqual (
1531                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1532                                 "<root />", sw.ToString (), "#2");
1533
1534                         // version BLABLA
1535                         sw.GetStringBuilder ().Length = 0;
1536                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1537                                 string.Format (xsltFragment, "BLABLA"))),
1538                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1539                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1540
1541                         Assert.AreEqual (
1542                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1543                                 "<root />", sw.ToString (), "#3");
1544                 }
1545
1546                 [Test]
1547                 public void Output_Method_Html_TextWriter ()
1548                 {
1549                         string options = null;
1550                         StringWriter sw = null;
1551                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1552                         XslTransform xsltProcessor = new XslTransform ();
1553
1554                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1555                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1556                                         <xsl:output method=""html"" {0} />
1557                                         <xsl:template match=""/"">
1558                                                 <xsl:element name=""html"">
1559                                                         <xsl:element name=""head"">
1560                                                                 <xsl:element name=""title"">Output Test</xsl:element>
1561                                                         </xsl:element>
1562                                                         <xsl:element name=""Body"">
1563                                                                 <xsl:element name=""BR"" />
1564                                                         </xsl:element>
1565                                                 </xsl:element>
1566                                         </xsl:template>
1567                                 </xsl:stylesheet>";
1568
1569                         XmlDocument xmlDoc = new XmlDocument ();
1570                         xmlDoc.LoadXml ("<dummy />");
1571
1572                         // indent not set, media-type not set
1573                         sw = new StringWriter ();
1574                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1575                                 string.Format (xsltFragment, string.Empty))),
1576                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1577                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1578
1579                         Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
1580                                 "<html>{0}" +
1581                                 "{1}<head>{0}" +
1582                                 "{1}{1}<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-16\">{0}" +
1583                                 "{1}{1}<title>Output Test</title>{0}" +
1584                                 "{1}</head>{0}" +
1585                                 "{1}<Body>{0}" +
1586                                 "{1}{1}<BR>{0}" +
1587                                 "{1}</Body>{0}" +
1588                                 "</html>", Environment.NewLine, "  "), sw.ToString (), "#1");
1589
1590                         // indent no, media-type not set
1591                         options = "indent=\"no\"";
1592                         sw.GetStringBuilder ().Length = 0;
1593                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1594                                 string.Format (xsltFragment, options))),
1595                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1596                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1597
1598                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1599                                 "<html>{0}" +
1600                                 "{1}<head>{0}" +
1601                                 "{1}{1}<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-16\">{0}" +
1602                                 "{1}{1}<title>Output Test</title>{0}" +
1603                                 "{1}</head>{0}" +
1604                                 "{1}<Body>{0}" +
1605                                 "{1}{1}<BR>{0}" +
1606                                 "{1}</Body>{0}" +
1607                                 "</html>", string.Empty, string.Empty), sw.ToString (), "#2");
1608
1609                         // indent yes, media-type "bla", omit-xml-declaration "no"
1610                         options = "indent=\"yes\" media-type=\"bla\"" +
1611                                                 " encoding=\"iso-8859-1\" omit-xml-declaration=\"no\"";
1612                         sw.GetStringBuilder ().Length = 0;
1613                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1614                                 string.Format (xsltFragment, options))),
1615                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1616                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1617
1618                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1619                                 "<html>{0}" +
1620                                 "{1}<head>{0}" +
1621                                 "{1}{1}<META http-equiv=\"Content-Type\" content=\"bla; charset=utf-16\">{0}" +
1622                                 "{1}{1}<title>Output Test</title>{0}" +
1623                                 "{1}</head>{0}" +
1624                                 "{1}<Body>{0}" +
1625                                 "{1}{1}<BR>{0}" +
1626                                 "{1}</Body>{0}" +
1627                                 "</html>", Environment.NewLine, "  "), sw.ToString (), "#3");
1628                 }
1629
1630                 [Test]
1631                 public void Output_Method_Html_Stream ()
1632                 {
1633                         string options = null;
1634                         MemoryStream ms = null;
1635                         string result = null;
1636                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1637                         XslTransform xsltProcessor = new XslTransform ();
1638
1639                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1640                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1641                                         <xsl:output method=""html"" {0} />
1642                                         <xsl:template match=""/"">
1643                                                 <xsl:element name=""html"">
1644                                                         <xsl:element name=""head"">
1645                                                                 <xsl:element name=""title"">Output Test</xsl:element>
1646                                                         </xsl:element>
1647                                                         <xsl:element name=""Body"">
1648                                                                 <xsl:element name=""BR"" />
1649                                                         </xsl:element>
1650                                                 </xsl:element>
1651                                         </xsl:template>
1652                                 </xsl:stylesheet>";
1653
1654                         XmlDocument xmlDoc = new XmlDocument ();
1655                         xmlDoc.LoadXml ("<dummy />");
1656
1657                         // indent not set, media-type not set
1658                         ms = new MemoryStream ();
1659                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1660                                 string.Format (xsltFragment, string.Empty))),
1661                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1662                         xsltProcessor.Transform (xmlDoc, xsltArgs, ms, new XmlUrlResolver ());
1663                         ms.Position = 0;
1664                         using (StreamReader sr = new StreamReader (ms, true)) {
1665                                 result = sr.ReadToEnd ();
1666                         }
1667
1668                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1669                                 "<html>{0}" +
1670                                 "{1}<head>{0}" +
1671                                 "{1}{1}<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">{0}" +
1672                                 "{1}{1}<title>Output Test</title>{0}" +
1673                                 "{1}</head>{0}" +
1674                                 "{1}<Body>{0}" +
1675                                 "{1}{1}<BR>{0}" +
1676                                 "{1}</Body>{0}" +
1677                                 "</html>", Environment.NewLine, "  "), result, "#1");
1678
1679                         // indent no, media-type not set
1680                         options = "indent=\"no\"";
1681                         ms = new MemoryStream ();
1682                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1683                                 string.Format (xsltFragment, options))),
1684                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1685                         xsltProcessor.Transform (xmlDoc, xsltArgs, ms, new XmlUrlResolver ());
1686                         ms.Position = 0;
1687                         using (StreamReader sr = new StreamReader (ms, true)) {
1688                                 result = sr.ReadToEnd ();
1689                         }
1690
1691                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1692                                 "<html>{0}" +
1693                                 "{1}<head>{0}" +
1694                                 "{1}{1}<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">{0}" +
1695                                 "{1}{1}<title>Output Test</title>{0}" +
1696                                 "{1}</head>{0}" +
1697                                 "{1}<Body>{0}" +
1698                                 "{1}{1}<BR>{0}" +
1699                                 "{1}</Body>{0}" +
1700                                 "</html>", string.Empty, string.Empty), result, "#2");
1701
1702                         // indent yes, media-type "bla", omit-xml-declaration "no"
1703                         options = "indent=\"yes\" media-type=\"bla\"" +
1704                                                 " encoding=\"iso-8859-1\" omit-xml-declaration=\"no\"";
1705                         ms = new MemoryStream ();
1706                         xsltProcessor.Load (new XmlTextReader (new StringReader (
1707                                 string.Format (xsltFragment, options))),
1708                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1709                         xsltProcessor.Transform (xmlDoc, xsltArgs, ms, new XmlUrlResolver ());
1710                         ms.Position = 0;
1711                         using (StreamReader sr = new StreamReader (ms, true)) {
1712                                 result = sr.ReadToEnd ();
1713                         }
1714
1715                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1716                                 "<html>{0}" +
1717                                 "{1}<head>{0}" +
1718                                 "{1}{1}<META http-equiv=\"Content-Type\" content=\"bla; charset=iso-8859-1\">{0}" +
1719                                 "{1}{1}<title>Output Test</title>{0}" +
1720                                 "{1}</head>{0}" +
1721                                 "{1}<Body>{0}" +
1722                                 "{1}{1}<BR>{0}" +
1723                                 "{1}</Body>{0}" +
1724                                 "</html>", Environment.NewLine, "  "), result, "#3");
1725                 }
1726
1727                 [Test]
1728                 [ExpectedException (typeof (XsltCompileException))]
1729                 public void Output_Unknown_Attribute ()
1730                 {
1731                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1732                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">
1733                                         <xsl:output whatever="""" />
1734                                 </xsl:stylesheet>";
1735                         XslTransform xsltProcessor = new XslTransform ();
1736                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1737                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1738                 }
1739
1740                 [Test]
1741                 public void Output_Unknown_Attribute_ForwardsCompatible ()
1742                 {
1743                         StringWriter sw = new StringWriter ();
1744                         XsltArgumentList xsltArgs = new XsltArgumentList ();
1745                         XslTransform xsltProcessor = new XslTransform ();
1746                         XmlDocument xmlDoc = new XmlDocument ();
1747                         xmlDoc.LoadXml ("<dummy />");
1748
1749                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1750                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.5"">
1751                                         <xsl:output whatever="""" />
1752                                         <xsl:template match=""/"">
1753                                                 <root />
1754                                         </xsl:template>
1755                                 </xsl:stylesheet>";
1756
1757                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1758                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1759                         xsltProcessor.Transform (xmlDoc, xsltArgs, sw, new XmlUrlResolver ());
1760
1761                         Assert.AreEqual (
1762                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
1763                                 "<root />", sw.ToString (), "#1");
1764                 }
1765
1766                 [Test]
1767                 public void Output_Unknown_Attribute_NonDefaultNamespace ()
1768                 {
1769                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
1770                                 <xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" xmlns:tst=""something"" version=""1.0"">
1771                                         <xsl:output tst:whatever="""" />
1772                                 </xsl:stylesheet>";
1773                         XslTransform xsltProcessor = new XslTransform ();
1774                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1775                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1776                 }
1777
1778                 // http://support.microsoft.com/kb/832757/en-us
1779                 [Test]
1780                 public void FormatNumber_KB_832757 ()
1781                 {
1782                         string xsltFragment = @"<?xml version=""1.0"" encoding=""UTF-8""?>
1783                                 <xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
1784                                         <xsl:output method=""xml"" version=""1.0"" encoding=""UTF-8"" indent=""yes"" />
1785                                         <xsl:template match=""/"">
1786                                                 <table>
1787                                                         <xsl:apply-templates />
1788                                                 </table>
1789                                         </xsl:template>
1790                                         <xsl:template match=""number"">
1791                                                 <tr><td><xsl:value-of select=""format-number(.,'#,##0;(#,##0)')""/></td></tr>
1792                                         </xsl:template>
1793                                 </xsl:stylesheet>";
1794
1795                         XmlDocument xmlDoc = new XmlDocument ();
1796                         xmlDoc.LoadXml ("<root><number>1000</number></root>");
1797
1798                         StringWriter sw = new StringWriter ();
1799                         XslTransform xsltProcessor = new XslTransform ();
1800                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1801                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1802                         xsltProcessor.Transform (xmlDoc, new XsltArgumentList (), sw, 
1803                                 new XmlUrlResolver ());
1804
1805                         Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
1806                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>{0}" +
1807                                 "<table>{0}" +
1808                                 "  <tr>{0}" +
1809                                 "    <td>1,000</td>{0}" +
1810                                 "  </tr>{0}" +
1811                                 "</table>", Environment.NewLine), sw.ToString ());
1812                 }
1813
1814                 // http://support.microsoft.com/kb/293469/en-us
1815                 [Test]
1816                 public void FormatNumber_KB_293469 ()
1817                 {
1818                         string xsltFragment = @"<?xml version=""1.0""?>
1819                                 <xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
1820                                         <xsl:output method=""xml"" indent=""yes"" />
1821                                         <xsl:decimal-format name=""european"" decimal-separator="","" grouping-separator=""."" />
1822                                         <xsl:template match=""/"">
1823                                                 <xsl:element name=""html"">
1824                                                         <xsl:element name=""body"">
1825                                                                 <xsl:apply-templates select=""root/amount"" />
1826                                                         </xsl:element>
1827                                                 </xsl:element>
1828                                         </xsl:template>
1829                                         <xsl:template match=""amount"">
1830                                                 <xsl:value-of select=""format-number(., '###.###,00', 'european')""/>
1831                                         </xsl:template>
1832                                 </xsl:stylesheet>";
1833
1834                         XmlDocument xmlDoc = new XmlDocument ();
1835                         xmlDoc.LoadXml ("<root><amount currency='USD'>44442.7</amount></root>");
1836
1837                         StringWriter sw = new StringWriter ();
1838                         XslTransform xsltProcessor = new XslTransform ();
1839                         xsltProcessor.Load (new XmlTextReader (new StringReader (xsltFragment)),
1840                                 new XmlUrlResolver (), AppDomain.CurrentDomain.Evidence);
1841                         xsltProcessor.Transform (xmlDoc, new XsltArgumentList (), sw,
1842                                 new XmlUrlResolver ());
1843
1844                         Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
1845                                 "<?xml version=\"1.0\" encoding=\"utf-16\"?>{0}" +
1846                                 "<html>{0}" +
1847                                 "  <body>44.442,70</body>{0}" +
1848                                 "</html>", Environment.NewLine), sw.ToString ());
1849                 }
1850
1851                 [Test]
1852                 [Category ("NotDotNet")]
1853                 // MS bug: the output must be well-formed XML general entity
1854                 // (doctype must not appear after text nodes).
1855                 public void DocTypeAfterText ()
1856                 {
1857                         string xsl = @"
1858 <xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
1859     <xsl:output doctype-system='system'/>
1860     <xsl:template match='/'>
1861         <xsl:text xml:space='preserve'> a </xsl:text>
1862         <foo/>
1863     </xsl:template>
1864 </xsl:stylesheet>";
1865                         XslTransform t = new XslTransform ();
1866                         t.Load (new XmlTextReader (xsl, XmlNodeType.Document, null));
1867                         XmlDocument doc = new XmlDocument ();
1868                         try {
1869                                 t.Transform (new XPathDocument (
1870                                              new StringReader ("<root/>")),
1871                                              null, TextWriter.Null);
1872                                 Assert.Fail ("should fail; doctype is not allowed after whitespace. See XSLT 1.0 section 16.1.");
1873                         } catch {
1874                         }
1875                 }
1876
1877                 [Test]
1878                 public void StripSpace ()
1879                 {
1880                         string result = @"
1881 MonoDevelop
1882 ProjectTemplates
1883 FileTemplates
1884 IDE
1885 StartupHandlers
1886 FileTemplateTypes
1887 Workspace
1888 Applications
1889 Services
1890 ";
1891
1892                         XslTransform t = new XslTransform ();
1893                         t.Load ("Test/XmlFiles/xsl/stripspace.xsl");
1894                         XPathDocument d = new XPathDocument (
1895                                 "Test/XmlFiles/xsl/stripspace.xml", XmlSpace.Preserve);
1896                         StringWriter sw = new StringWriter ();
1897                         t.Transform (d, null, sw);
1898                         Assert.AreEqual (result, sw.ToString ());
1899                 }
1900
1901                 [Test]
1902                 public void CurrentInSelect ()
1903                 {
1904                         XslTransform t = new XslTransform ();
1905                         t.Load ("Test/XmlFiles/xsl/current-in-select.xsl");
1906                         XPathDocument d = new XPathDocument (
1907                                 "Test/XmlFiles/xsl/current-in-select.xml", XmlSpace.Preserve);
1908                         StringWriter sw = new StringWriter ();
1909                         t.Transform (d, null, sw);
1910                         using (StreamReader sr = File.OpenText (
1911                                "Test/XmlFiles/xsl/current-in-select.ref")) {
1912                                 string s = sr.ReadToEnd ();
1913                                 Assert.AreEqual (s, sw.ToString ());
1914                         }
1915                 }
1916
1917                 [Test]
1918                 public void CallTemplateSignificantWhitespace ()
1919                 {
1920                         // bug #82357
1921                         string xsl = @"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
1922   <xsl:template name='foo' xml:space='preserve'>
1923     <xsl:call-template name='bar'>
1924       <xsl:with-param name='hoge' select='hoge' />
1925     </xsl:call-template>
1926   </xsl:template>
1927
1928   <xsl:template name='bar'>
1929   </xsl:template>
1930 </xsl:stylesheet>";
1931                         XslTransform t = new XslTransform ();
1932                         t.Load (new XmlTextReader (new StringReader (xsl)));
1933                         t.Transform (new XPathDocument (new StringReader ("<dummy/>")), null, new XmlTextWriter (TextWriter.Null));
1934                 }
1935
1936                 [Test]
1937                 public void Bug82493 ()
1938                 {
1939                         XslTransform transformationObj = new XslTransform ();
1940                         transformationObj.Load ("Test/XmlFiles/xsl/82493.xsl");
1941                         XmlDocument doc = new XmlDocument ();
1942                         doc.Load ("Test/XmlFiles/xsl/82493.xml");
1943                         XslExtensionClass GetCalculation = new XslExtensionClass ("a4");
1944                         XsltArgumentList xslExtensionArgList = new XsltArgumentList ();
1945                         xslExtensionArgList.AddExtensionObject ("urn:e", GetCalculation);
1946                         XmlTextWriter writer = new XmlTextWriter (TextWriter.Null);
1947                         transformationObj.Transform (doc, xslExtensionArgList, writer, null);
1948
1949                 }
1950
1951                 [Test]
1952                 public void BugNovell325482 ()
1953                 {
1954                         XmlDocument doc = new XmlDocument ();
1955                         doc.Load ("Test/XmlFiles/xsl/325482.xml");
1956                         XslTransform xt = new XslTransform ();
1957                         xt.Load ("Test/XmlFiles/xsl/325482.xsl");
1958                         xt.Transform (doc, null, TextWriter.Null);
1959                 }
1960
1961                 public class XslExtensionClass
1962                 {
1963                         private string paperType = String.Empty;
1964
1965                         public XslExtensionClass (string paperType)
1966                         {
1967                                 this.paperType = paperType;
1968                         }
1969
1970                         public int GetPageDimensions ()
1971                         {
1972                                 switch (this.paperType) {
1973                                 case "a4":
1974                                         return 210297;
1975                                 case "letter":
1976                                         return 216279;
1977                                 default:
1978                                         throw new ArgumentException ("Unknown page size type: " + this.paperType);
1979                                 }
1980                         }
1981                 }
1982
1983                 [Test] // bug #348786
1984                 public void ValueOfContainsExternalElements ()
1985                 {
1986                         string xsl = @"
1987 <xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
1988   <xsl:template match=""x"">
1989     <y>
1990       <xsl:value-of select=""@bar"">
1991         <!-- enter comment here -->
1992       </xsl:value-of>
1993     </y>
1994   </xsl:template>
1995 </xsl:stylesheet>";
1996                         new XslTransform ().Load (new XmlTextReader (xsl, XmlNodeType.Document, null));
1997                 }
1998
1999                 [Test] // bug #349035
2000                 public void CompareRTFAsStringNotNodeset ()
2001                 {
2002                         XslTransform xslt = new XslTransform ();
2003                         xslt.Load (new XmlTextReader (new StringReader (@"
2004 <xsl:stylesheet version=""1.0""
2005   xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
2006   <xsl:template name=""foo"">
2007     <xsl:param name=""bar""/>
2008     <xsl:if test=""$bar!=''"">
2009       <bar>bar is not empty:'<xsl:value-of select=""$bar""/>'</bar>
2010     </xsl:if>
2011     <xsl:if test=""$bar=''"">
2012       <bar>bar is empty</bar>
2013     </xsl:if>
2014   </xsl:template>
2015   <xsl:template match=""zap"">
2016     <xsl:call-template name=""foo"">
2017       <xsl:with-param name=""bar"">
2018         <xsl:for-each select=""@bar"">
2019           <xsl:value-of select="".""/>
2020         </xsl:for-each>
2021       </xsl:with-param>
2022     </xsl:call-template>
2023   </xsl:template>
2024 </xsl:stylesheet>"
2025                         )));
2026                         XPathDocument input = new XPathDocument (new StringReader (
2027                         @"<root>
2028         <zap bar=""HaHa""/>
2029         <zap/>
2030 </root>"
2031                 ));
2032                         StringWriter sw = new StringWriter ();
2033                         XmlTextWriter xtw = new XmlTextWriter (sw);
2034                         xslt.Transform (input, null, xtw);
2035                         string expected = "<bar>bar is not empty:'HaHa'</bar><bar>bar is empty</bar>";
2036                         Assert.AreEqual (expected, sw.ToString ());
2037                 }
2038
2039                 [Test]
2040                 public void Bug349111 ()
2041                 {
2042                         XslTransform xslt = new XslTransform ();
2043                         xslt.Load (new XmlTextReader (new StringReader (@"
2044 <xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
2045   <xsl:template match=""book"">
2046     <xsl:for-each select=""child::node()[position()]"">
2047       <yyy>
2048         <xsl:value-of select="".""/>
2049       </yyy>
2050     </xsl:for-each>
2051   </xsl:template>
2052 </xsl:stylesheet>"
2053                                 )));
2054                         XPathDocument input = new XPathDocument (new StringReader (@"
2055 <bookstore>
2056   <book> <title lang=""eng"">Harry Potter</title> <price>29.99</price> </book>
2057 </bookstore>"
2058                                 ));
2059                         StringWriter sw = new StringWriter ();
2060                         xslt.Transform (input, null, new XmlTextWriter (sw));
2061                         string expected = "<yyy>Harry Potter</yyy><yyy>29.99</yyy>";
2062                         Assert.AreEqual (expected, sw.ToString ());
2063                 }
2064
2065                 [Test]
2066                 public void Bug351939 ()
2067                 {
2068                         XslTransform xslt = new XslTransform ();
2069                         xslt.Load (new XmlTextReader (new StringReader (
2070 @"<xsl:stylesheet version=""1.0""
2071   xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
2072   <xsl:key name=""thekey"" match=""aa"" use=""''""/>
2073   <xsl:key name=""thekey"" match=""ab"" use=""''""/>
2074   <xsl:template match=""root"">
2075     <x>
2076       <foo><xsl:value-of select=""key('thekey','')[1]""/></foo>
2077       <bar><xsl:value-of select=""key('thekey','')[2]""/></bar>
2078       <baz><xsl:value-of select=""key('thekey','')[3]""/></baz>
2079       <tem><xsl:value-of select=""key('thekey','')[4]""/></tem>
2080     </x>
2081   </xsl:template>
2082 </xsl:stylesheet>")));
2083                         StringWriter sw = new StringWriter ();
2084                         xslt.Transform (new XPathDocument (new StringReader (
2085 @"<?xml version=""1.0""?>
2086 <root>
2087   <a>
2088     <aa>1</aa>
2089     <ab>2</ab>
2090   </a>
2091   <a>
2092     <aa>3</aa>
2093     <ab>4</ab>
2094   </a>
2095 </root>")), null, new XmlTextWriter (sw));
2096                         Assert.AreEqual ("<x><foo>1</foo><bar>2</bar><baz>3</baz><tem>4</tem></x>", sw.ToString ());
2097                 }
2098
2099                 [Test]
2100                 public void CopyOfIXPathNavigable ()
2101                 {
2102                         string xsl = @"
2103 <xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
2104   xmlns:foo='urn:Foo'>
2105   <xsl:template match='/'>
2106     <xsl:copy-of select='foo:MyCustomFunction()'/>
2107   </xsl:template>
2108 </xsl:stylesheet>";
2109                         string xml = @"
2110 <family>
2111   <person>
2112     <given-name age='10'>
2113       <name>Fred</name>
2114       <nick-name>Freddy</nick-name>
2115     </given-name>
2116     <family-name>Smith</family-name>
2117   </person>
2118   <person>
2119     <given-name age='10'>
2120       <name>Robert</name>
2121       <nick-name>Bob</nick-name>
2122     </given-name>
2123     <family-name>Smith</family-name>
2124   </person>
2125 </family>";
2126                         XslTransform t = new XslTransform ();
2127                         t.Load (new XPathDocument (new StringReader (xsl)));
2128                         XsltArgumentList args = new XsltArgumentList();
2129                         args.AddExtensionObject ("urn:Foo", new CopyOfIXPathNavigableClass ());
2130                         StringWriter sw = new StringWriter ();
2131                         t.Transform (new XPathDocument (new StringReader (xml)), args, new XmlTextWriter (sw));
2132                         Assert.AreEqual ("<root><child0 /><child1 /></root>", sw.ToString ());
2133                 }
2134
2135                 public class CopyOfIXPathNavigableClass
2136                 {
2137                         public object MyCustomFunction ()
2138                         {
2139                                 XmlDocument doc = new XmlDocument ();
2140                                 doc .LoadXml ("<root><child0 /><child1 /></root>");
2141                                 return doc.DocumentElement;
2142                         }
2143                 }
2144
2145                 [Test] // bug #316238
2146                 public void ResolveVariableInXsltArgumentList ()
2147                 {
2148                         ResolveVariableInXsltArgumentList ("Test/XmlFiles/xsl/316238-1.xsl");
2149                         ResolveVariableInXsltArgumentList ("Test/XmlFiles/xsl/316238-2.xsl");
2150                 }
2151
2152                 void ResolveVariableInXsltArgumentList (string file)
2153                 {
2154                         XmlDocument doc = new XmlDocument ();
2155                         doc.LoadXml ("<doc><element id=\"test\">this is a test</element></doc>");
2156                         XslTransform transform = new XslTransform ();
2157                         transform.Load (file);
2158                         //Stream outputStream = Console.OpenStandardOutput();
2159                         XsltArgumentList xsltArgs = new XsltArgumentList ();
2160                         xsltArgs.AddParam ("test", "", "test");
2161                         xsltArgs.AddParam ("doc", "", doc.CreateNavigator().Select ("*"));
2162                         transform.Transform (new XmlDocument (), xsltArgs, TextWriter.Null);
2163                 }
2164
2165                 [Test] // bug #378239
2166                 public void WhitespaceEntityInStylesheet ()
2167                 {
2168                         string xslt = @"<?xml version='1.0' encoding='UTF-8'?>
2169 <!DOCTYPE xsl:stylesheet [
2170 <!ENTITY nl '
2171 '>
2172 ]>
2173 <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
2174 <xsl:output method='text' omit-xml-declaration='yes'/>
2175
2176 <xsl:template match='/'>
2177 <xsl:text>&nl;Hello&nl;World</xsl:text>
2178 </xsl:template>
2179 </xsl:stylesheet>";
2180                         string expected = @"
2181 Hello
2182 World";
2183                         XslTransform t = new XslTransform ();
2184                         t.Load (new XPathDocument (new StringReader (xslt)));
2185                         StringWriter sw = new StringWriter ();
2186                         t.Transform (new XPathDocument (new StringReader ("<test/>")), null, sw);
2187                         Assert.AreEqual (expected, sw.ToString ());
2188                 }
2189
2190                 [Test] // bug #556619
2191                 public void RejectCurrencySymbolAsNumber ()
2192                 {
2193                         XslTransform xslt = new XslTransform ();
2194                         StringWriter sw = new StringWriter ();
2195                         string s =
2196 @"<?xml version=""1.0""?>
2197
2198 <xsl:stylesheet
2199   version=""1.0""
2200   xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
2201   >
2202
2203   <xsl:template name=""F"">
2204     <xsl:param name=""p""/>
2205     <xsl:choose>
2206       <xsl:when test=""number($p)"">
2207 YES <xsl:value-of select=""number($p)""/>
2208       </xsl:when>
2209       <xsl:otherwise>
2210 NO
2211       </xsl:otherwise>
2212     </xsl:choose>
2213   </xsl:template>
2214   <xsl:template match=""/"">
2215     <xsl:call-template name=""F"">
2216       <xsl:with-param name=""p"">$4$2</xsl:with-param>
2217     </xsl:call-template>
2218   </xsl:template>
2219
2220 </xsl:stylesheet>";
2221                         xslt.Load (new XmlTextReader (new StringReader (s)));
2222                         xslt.Transform (new XPathDocument (new StringReader (
2223 @"<?xml version=""1.0""?>
2224 <root>
2225 </root>")), null, sw);
2226                         Assert.IsTrue (sw.ToString ().IndexOf ("NO") > 0);
2227                 }
2228
2229 #if NET_2_0
2230                 [Test] // bug #349375
2231                 public void PreserveWhitespace ()
2232                 {
2233                         XslCompiledTransform xslt = new XslCompiledTransform ();
2234                         xslt.Load (new XmlTextReader (new StringReader (@"
2235 <xsl:stylesheet
2236   version=""1.0""
2237   xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
2238   >
2239   <xsl:output omit-xml-declaration='yes' />
2240   <xsl:strip-space elements='*'/>
2241   <xsl:preserve-space elements='p span'/>
2242
2243   <xsl:template name='foo'>
2244     <xsl:for-each select='node()'>
2245         <xsl:attribute name='yes-one-node'/>
2246         <xsl:value-of select='.'/>
2247     </xsl:for-each>
2248     <xsl:if test='not(node())'>
2249         <xsl:attribute name='not-node'/>
2250         <xsl:value-of select='.'/>
2251     </xsl:if>
2252   </xsl:template>
2253
2254   <xsl:template match='p'>
2255     <y>
2256       <xsl:for-each select='child::node()[position()]'>
2257         <xsl:choose>
2258           <xsl:when test='name()=""span""'>
2259               <t>
2260                 <xsl:call-template name='foo'/>
2261               </t>
2262           </xsl:when>
2263         </xsl:choose>
2264       </xsl:for-each>
2265     </y>
2266   </xsl:template>
2267
2268 </xsl:stylesheet>")));
2269                         StringWriter sw = new StringWriter ();
2270                         xslt.Transform (new XmlTextReader (new StringReader (@"
2271 <root>
2272   <l0>
2273     <p>
2274       <span>1</span>
2275       <span> </span>
2276     </p>
2277   </l0>
2278 </root>")), null, sw);
2279                         Assert.AreEqual (@"<y><t yes-one-node="""">1</t><t yes-one-node=""""> </t></y>", sw.ToString ());
2280                 }
2281
2282                 [Test] // reverse case of #349375
2283                 [Category ("NotWorking")]
2284 //              [Category ("NotDotNet")]
2285                 public void PreserveWhitespace2 ()
2286                 {
2287                         XslCompiledTransform xslt = new XslCompiledTransform ();
2288                         xslt.Load (new XmlTextReader (new StringReader (@"
2289 <xsl:stylesheet
2290   version=""1.0""
2291   xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
2292   >
2293   <xsl:output omit-xml-declaration='yes' />
2294   <xsl:preserve-space elements='*'/>
2295   <xsl:strip-space elements='p span'/>
2296
2297   <xsl:template name='foo'>
2298     <xsl:for-each select='node()'>
2299         <xsl:attribute name='yes-one-node'/>
2300         <xsl:value-of select='.'/>
2301     </xsl:for-each>
2302     <xsl:if test='not(node())'>
2303         <xsl:attribute name='not-node'/>
2304         <xsl:value-of select='.'/>
2305     </xsl:if>
2306   </xsl:template>
2307
2308   <xsl:template match='p'>
2309     <y>
2310       <xsl:for-each select='child::node()[position()]'>
2311         <xsl:choose>
2312           <xsl:when test='name()=""span""'>
2313               <t>
2314                 <xsl:call-template name='foo'/>
2315               </t>
2316           </xsl:when>
2317         </xsl:choose>
2318       </xsl:for-each>
2319     </y>
2320   </xsl:template>
2321
2322 </xsl:stylesheet>")));
2323                         StringWriter sw = new StringWriter ();
2324                         xslt.Transform (new XmlTextReader (new StringReader (@"
2325 <root>
2326   <l0>
2327     <p>
2328       <span>1</span>
2329       <span> </span>
2330     </p>
2331   </l0>
2332 </root>")), null, sw);
2333 //                      Assert.AreEqual (@"<y><t yes-one-node="""">1</t><t not-node=""""></t></y>", sw.ToString ());
2334                         Assert.AreEqual ("\r\n  \r\n    <y><t yes-one-node=\"\">1</t><t not-node=\"\"></t></y>\r\n  \r\n", sw.ToString ());
2335                 }
2336
2337                 [Test]
2338                 public void CompiledTransform_Fragment () // bug #391424
2339                 {
2340                         XslCompiledTransform xslTransform = new XslCompiledTransform ();
2341                         XsltSettings settings = new XsltSettings ();
2342                         settings.EnableDocumentFunction = true;
2343                         xslTransform.Load ("Test/XmlFiles/xsl/391424.xsl", settings, new XmlUrlResolver ());
2344                         StringWriter sw = new StringWriter ();
2345                         xslTransform.Transform (new XPathDocument ("Test/XmlFiles/xsl/391424.xml", XmlSpace.Preserve), null, sw);
2346                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>Document found", sw.ToString ());
2347                 }
2348
2349                 [Test]
2350                 public void XslTextElement_PreservesWhitespace () // bug 450797
2351                 {
2352                         XslCompiledTransform xslt = new XslCompiledTransform ();
2353                         xslt.Load (new XmlTextReader (new StringReader (@"
2354 <xsl:stylesheet
2355   xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
2356   version=""1.0"">
2357   <xsl:output method='text' omit-xml-declaration='yes'/>
2358   <xsl:template match='foo'>
2359     <xsl:text> </xsl:text>
2360   </xsl:template>
2361 </xsl:stylesheet>")));
2362                         StringWriter sw = new StringWriter ();
2363                         xslt.Transform (new XmlTextReader (new StringReader (@"<foo>bar</foo>")), null, sw);
2364                         Assert.AreEqual (" ", sw.ToString ());
2365                 }
2366
2367                 [Test]
2368                 public void Bug487065 ()
2369                 {
2370                         using (XmlReader input = GetInput ()) {
2371                                 using (XmlWriter output = XmlWriter.Create (Path.Combine(Path.GetTempPath(), "out.xml"))) {
2372                                         PreProcess (input, output);
2373                                         Assert.IsTrue (valueHasBeenSet, "#1");
2374                                 }
2375                         }
2376                 }
2377
2378                 private static XmlReader GetInput ()
2379                 {
2380                         return XmlReader.Create (new StringReader ("<cb:config-template xmlns:cb=\"urn:ccnet.config.builder\"><cb:define name=\"var1\">value1</cb:define></cb:config-template>"));
2381                 }
2382
2383                 private void PreProcess (XmlReader input, XmlWriter output)
2384                 {
2385                         var xsltsettings = new XsltSettings (true, true);
2386                         var xsltpreprocess = new XslCompiledTransform (true);
2387
2388                         var stream =
2389                                 new StringReader (@"
2390 <xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
2391  xmlns:msxsl='urn:schemas-microsoft-com:xslt'
2392  xmlns:cb='urn:ccnet.config.builder'    
2393  xmlns:env='environment'
2394  xmlns:exsl='http://exslt.org/common'
2395  exclude-result-prefixes='msxsl cb env exsl'>
2396   <xsl:template match='cb:define[not(*) and @name]'>
2397     <xsl:for-each select='env:define_text_constant(@name,.)'/>
2398   </xsl:template>
2399 </xsl:stylesheet>");
2400
2401                         using (XmlReader xsltreader = XmlReader.Create (stream))
2402                                 xsltpreprocess.Load (xsltreader, xsltsettings, new XmlUrlResolver());
2403
2404                         var xsltargs = new XsltArgumentList ();
2405
2406                         // The XSLT calls extension functions in _current_env.
2407                         xsltargs.AddExtensionObject ("environment", this);
2408                         xsltpreprocess.Transform (input, xsltargs, output, null);
2409                 }
2410
2411                 public void define_text_constant (string name, string value)
2412                 {
2413                         Assert.AreEqual("var1", name, "#a1");
2414                         Assert.AreEqual("value1", value, "#a2");
2415                         valueHasBeenSet = true;
2416                 }
2417
2418                 private bool valueHasBeenSet;
2419 #endif
2420         }
2421 }