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