XslTransform.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. // UnmanagedXslTransform
  2. //
  3. // Authors:
  4. // Tim Coleman <[email protected]>
  5. // Gonzalo Paniagua Javier ([email protected])
  6. // Ben Maurer ([email protected])
  7. //
  8. // (C) Copyright 2002 Tim Coleman
  9. // (c) 2003 Ximian Inc. (http://www.ximian.com)
  10. // (C) Ben Maurer 2003
  11. //
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. // DO NOT MOVE THIS FILE. WE WANT HISTORY
  33. using System;
  34. using System.Collections;
  35. using System.IO;
  36. using System.Security.Policy;
  37. using System.Text;
  38. using System.Runtime.InteropServices;
  39. using System.Xml.XPath;
  40. using BF = System.Reflection.BindingFlags;
  41. namespace System.Xml.Xsl
  42. {
  43. internal unsafe sealed class UnmanagedXslTransform : XslTransformImpl
  44. {
  45. #region Fields
  46. IntPtr stylesheet;
  47. Hashtable extensionObjectCache = new Hashtable();
  48. #endregion
  49. #region Constructors
  50. public UnmanagedXslTransform ()
  51. {
  52. stylesheet = IntPtr.Zero;
  53. }
  54. #endregion
  55. #region Methods
  56. ~UnmanagedXslTransform ()
  57. {
  58. FreeStylesheetIfNeeded ();
  59. }
  60. void FreeStylesheetIfNeeded ()
  61. {
  62. if (stylesheet != IntPtr.Zero) {
  63. xsltFreeStylesheet (stylesheet);
  64. stylesheet = IntPtr.Zero;
  65. }
  66. }
  67. public override void Load (string url, XmlResolver resolver)
  68. {
  69. FreeStylesheetIfNeeded ();
  70. stylesheet = xsltParseStylesheetFile (url);
  71. Cleanup ();
  72. if (stylesheet == IntPtr.Zero)
  73. throw new XmlException ("Error creating stylesheet");
  74. }
  75. public override void Load (XmlReader stylesheet, XmlResolver resolver, Evidence evidence)
  76. {
  77. FreeStylesheetIfNeeded ();
  78. // Create a document for the stylesheet
  79. XmlDocument doc = new XmlDocument ();
  80. doc.Load (stylesheet);
  81. // Store the XML in a StringBuilder
  82. StringWriter sr = new UTF8StringWriter ();
  83. XmlTextWriter writer = new XmlTextWriter (sr);
  84. doc.Save (writer);
  85. this.stylesheet = GetStylesheetFromString (sr.GetStringBuilder ().ToString ());
  86. Cleanup ();
  87. if (this.stylesheet == IntPtr.Zero)
  88. throw new XmlException ("Error creating stylesheet");
  89. }
  90. public override void Load (XPathNavigator stylesheet, XmlResolver resolver, Evidence evidence)
  91. {
  92. FreeStylesheetIfNeeded ();
  93. StringWriter sr = new UTF8StringWriter ();
  94. Save (stylesheet, sr);
  95. this.stylesheet = GetStylesheetFromString (sr.GetStringBuilder ().ToString ());
  96. Cleanup ();
  97. if (this.stylesheet == IntPtr.Zero)
  98. throw new XmlException ("Error creating stylesheet");
  99. }
  100. static IntPtr GetStylesheetFromString (string xml)
  101. {
  102. IntPtr result = IntPtr.Zero;
  103. IntPtr xmlDoc = xmlParseDoc (xml);
  104. if (xmlDoc == IntPtr.Zero) {
  105. Cleanup ();
  106. throw new XmlException ("Error parsing stylesheet");
  107. }
  108. result = xsltParseStylesheetDoc (xmlDoc);
  109. Cleanup ();
  110. if (result == IntPtr.Zero)
  111. throw new XmlException ("Error creating stylesheet");
  112. return result;
  113. }
  114. IntPtr ApplyStylesheet (IntPtr doc, string[] argArr, Hashtable extobjects)
  115. {
  116. if (stylesheet == IntPtr.Zero)
  117. throw new XmlException ("No style sheet!");
  118. IntPtr result;
  119. if (extobjects == null || extobjects.Count == 0) {
  120. // If there are no extension objects, use the simple (old) method.
  121. result = xsltApplyStylesheet (stylesheet, doc, argArr);
  122. } else {
  123. // If there are extension objects, create a context and register the functions.
  124. IntPtr context = xsltNewTransformContext(stylesheet, doc);
  125. if (context == IntPtr.Zero) throw new XmlException("Error creating transformation context.");
  126. try {
  127. foreach (string ns in extobjects.Keys) {
  128. object ext = extobjects[ns];
  129. if (extensionObjectCache.ContainsKey(ext)) {
  130. foreach (ExtensionFunctionHolder ef in (ArrayList)extensionObjectCache[ext]) {
  131. int ret = xsltRegisterExtFunction(context, ef.name, ef.ns, ef.func);
  132. if (ret != 0) throw new XmlException("Could not reregister extension function " + ef.name + " in " + ef.ns);
  133. }
  134. } else {
  135. object extsrc;
  136. System.Type type;
  137. System.Collections.IEnumerable methods;
  138. // As an added bonus, if the extension object is a UseStaticMethods object
  139. // (defined below), then add the static methods of the specified type.
  140. if (ext is UseStaticMethods) {
  141. type = ((UseStaticMethods)ext).Type;
  142. methods = type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
  143. extsrc = null;
  144. } else {
  145. extsrc = ext;
  146. type = ext.GetType();
  147. methods = type.GetMethods();
  148. }
  149. ArrayList functionstocache = new ArrayList();
  150. Hashtable alreadyadded = new Hashtable ();
  151. foreach (System.Reflection.MethodInfo mi in methods) {
  152. if (alreadyadded.ContainsKey(mi.Name)) continue; // don't add twice
  153. alreadyadded[mi.Name] = 1;
  154. // Simple extension function delegate
  155. ExtensionFunction func = new ExtensionFunction(new ReflectedExtensionFunction(type, extsrc, mi.Name).Function);
  156. // Delegate for libxslt library call
  157. libxsltXPathFunction libfunc = new libxsltXPathFunction(new ExtensionFunctionWrapper(func).Function);
  158. int ret = xsltRegisterExtFunction(context, mi.Name, ns, libfunc);
  159. if (ret != 0) throw new XmlException("Could not register extension function " + mi.DeclaringType.FullName + "." + mi.Name + " in " + ns);
  160. ExtensionFunctionHolder efh;
  161. efh.name = mi.Name;
  162. efh.ns = ns;
  163. efh.func = libfunc;
  164. functionstocache.Add(efh);
  165. }
  166. extensionObjectCache[ext] = functionstocache;
  167. }
  168. }
  169. result = xsltApplyStylesheetUser(stylesheet, doc, argArr, null, IntPtr.Zero, context);
  170. } finally {
  171. xsltFreeTransformContext(context);
  172. }
  173. }
  174. if (result == IntPtr.Zero)
  175. throw new XmlException ("Error applying style sheet");
  176. return result;
  177. }
  178. static void Cleanup ()
  179. {
  180. //xsltCleanupGlobals ();
  181. //xmlCleanupParser ();
  182. }
  183. static string GetStringFromDocument (IntPtr doc, IntPtr stylesheet)
  184. {
  185. IntPtr mem = IntPtr.Zero;
  186. int size = 0;
  187. int res = xsltSaveResultToString (ref mem, ref size, doc,
  188. stylesheet);
  189. if (res == -1)
  190. throw new XmlException ("xsltSaveResultToString () failed.");
  191. string docStr = Marshal.PtrToStringAnsi (mem, size);
  192. Marshal.FreeHGlobal (mem);
  193. return docStr;
  194. }
  195. string ApplyStylesheetAndGetString (IntPtr doc, string[] argArr, Hashtable extobjects)
  196. {
  197. IntPtr xmlOutput = ApplyStylesheet (doc,
  198. argArr == null ? new string [0] : argArr,
  199. extobjects == null ? new Hashtable () : extobjects);
  200. string strOutput = GetStringFromDocument (xmlOutput, stylesheet);
  201. xmlFreeDoc (xmlOutput);
  202. return strOutput;
  203. }
  204. IntPtr GetDocumentFromNavigator (XPathNavigator nav)
  205. {
  206. StringWriter sr = new UTF8StringWriter ();
  207. Save (nav, sr);
  208. IntPtr xmlInput = xmlParseDoc (sr.GetStringBuilder ().ToString ());
  209. if (xmlInput == IntPtr.Zero)
  210. throw new XmlException ("Error getting XML from input");
  211. return xmlInput;
  212. }
  213. public override void Transform (XPathNavigator input, XsltArgumentList args, XmlWriter output, XmlResolver resolver)
  214. {
  215. if (input == null)
  216. throw new ArgumentNullException ("input");
  217. if (output == null)
  218. throw new ArgumentNullException ("output");
  219. StringWriter writer = new UTF8StringWriter ();
  220. IntPtr inputDoc = GetDocumentFromNavigator (input);
  221. string[] argArr = null;
  222. Hashtable extensionObjects = null;
  223. if (args != null) {
  224. extensionObjects = args.extensionObjects;
  225. argArr = new string[args.parameters.Count * 2 + 1];
  226. int index = 0;
  227. foreach (object key in args.parameters.Keys) {
  228. argArr [index++] = key.ToString();
  229. object value = args.parameters [key];
  230. if (value is Boolean)
  231. argArr [index++] = XmlConvert.ToString((bool) value); // FIXME: How to encode it for libxslt?
  232. else if (value is Double)
  233. argArr [index++] = XmlConvert.ToString((double) value); // FIXME: How to encode infinity's and Nan?
  234. else
  235. argArr [index++] = "'" + value.ToString() + "'"; // FIXME: How to encode "'"?
  236. }
  237. argArr[index] = null;
  238. }
  239. string transform = ApplyStylesheetAndGetString (inputDoc, argArr, extensionObjects);
  240. xmlFreeDoc (inputDoc);
  241. Cleanup ();
  242. writer.Write (transform);
  243. writer.Flush ();
  244. output.WriteRaw (writer.GetStringBuilder ().ToString ());
  245. output.Flush ();
  246. }
  247. public override void Transform (XPathNavigator input, XsltArgumentList args, TextWriter output, XmlResolver resolver)
  248. {
  249. Transform(input, args, new XmlTextWriter(output), resolver);
  250. }
  251. public override void Transform(string inputfile, string outputfile, XmlResolver resolver)
  252. {
  253. IntPtr xmlDocument = IntPtr.Zero;
  254. IntPtr resultDocument = IntPtr.Zero;
  255. try {
  256. xmlDocument = xmlParseFile (inputfile);
  257. if (xmlDocument == IntPtr.Zero)
  258. throw new XmlException ("Error parsing input file");
  259. resultDocument = ApplyStylesheet (xmlDocument, null, null);
  260. if (-1 == xsltSaveResultToFilename (outputfile, resultDocument, stylesheet, 0))
  261. throw new XmlException ("Error in xsltSaveResultToFilename");
  262. } finally {
  263. if (xmlDocument != IntPtr.Zero)
  264. xmlFreeDoc (xmlDocument);
  265. if (resultDocument != IntPtr.Zero)
  266. xmlFreeDoc (resultDocument);
  267. Cleanup ();
  268. }
  269. }
  270. static void Save (XmlReader rdr, TextWriter baseWriter)
  271. {
  272. XmlTextWriter writer = new XmlTextWriter (baseWriter);
  273. while (rdr.Read ()) {
  274. switch (rdr.NodeType) {
  275. case XmlNodeType.CDATA:
  276. writer.WriteCData (rdr.Value);
  277. break;
  278. case XmlNodeType.Comment:
  279. writer.WriteComment (rdr.Value);
  280. break;
  281. case XmlNodeType.DocumentType:
  282. writer.WriteDocType (rdr.Value, null, null, null);
  283. break;
  284. case XmlNodeType.Element:
  285. writer.WriteStartElement (rdr.Name, rdr.Value);
  286. while (rdr.MoveToNextAttribute ())
  287. writer.WriteAttributes (rdr, true);
  288. break;
  289. case XmlNodeType.EndElement:
  290. writer.WriteEndElement ();
  291. break;
  292. case XmlNodeType.ProcessingInstruction:
  293. writer.WriteProcessingInstruction (rdr.Name, rdr.Value);
  294. break;
  295. case XmlNodeType.Text:
  296. writer.WriteString (rdr.Value);
  297. break;
  298. case XmlNodeType.Whitespace:
  299. writer.WriteWhitespace (rdr.Value);
  300. break;
  301. case XmlNodeType.XmlDeclaration:
  302. writer.WriteStartDocument ();
  303. break;
  304. }
  305. }
  306. writer.Close ();
  307. }
  308. static void Save (XPathNavigator navigator, TextWriter writer)
  309. {
  310. XmlTextWriter xmlWriter = new XmlTextWriter (writer);
  311. WriteTree (navigator, xmlWriter);
  312. xmlWriter.WriteEndDocument ();
  313. xmlWriter.Flush ();
  314. }
  315. // Walks the XPathNavigator tree recursively
  316. static void WriteTree (XPathNavigator navigator, XmlTextWriter writer)
  317. {
  318. WriteCurrentNode (navigator, writer);
  319. if (navigator.MoveToFirstNamespace (XPathNamespaceScope.Local)) {
  320. do {
  321. WriteCurrentNode (navigator, writer);
  322. } while (navigator.MoveToNextNamespace (XPathNamespaceScope.Local));
  323. navigator.MoveToParent ();
  324. }
  325. if (navigator.MoveToFirstAttribute ()) {
  326. do {
  327. WriteCurrentNode (navigator, writer);
  328. } while (navigator.MoveToNextAttribute ());
  329. navigator.MoveToParent ();
  330. }
  331. if (navigator.MoveToFirstChild ()) {
  332. do {
  333. WriteTree (navigator, writer);
  334. } while (navigator.MoveToNext ());
  335. navigator.MoveToParent ();
  336. if (navigator.NodeType != XPathNodeType.Root)
  337. writer.WriteEndElement ();
  338. } else if (navigator.NodeType == XPathNodeType.Element) {
  339. writer.WriteEndElement ();
  340. }
  341. }
  342. // Format the output
  343. static void WriteCurrentNode (XPathNavigator navigator, XmlTextWriter writer)
  344. {
  345. switch (navigator.NodeType) {
  346. case XPathNodeType.Root:
  347. writer.WriteStartDocument ();
  348. break;
  349. case XPathNodeType.Namespace:
  350. if (navigator.Name == String.Empty)
  351. writer.WriteAttributeString ("xmlns", navigator.Value);
  352. else
  353. writer.WriteAttributeString ("xmlns",
  354. navigator.Name,
  355. "http://www.w3.org/2000/xmlns/",
  356. navigator.Value);
  357. break;
  358. case XPathNodeType.Attribute:
  359. writer.WriteAttributeString (navigator.Name, navigator.Value);
  360. break;
  361. case XPathNodeType.Comment:
  362. writer.WriteComment (navigator.Value);
  363. break;
  364. case XPathNodeType.Element:
  365. writer.WriteStartElement (navigator.Name);
  366. break;
  367. case XPathNodeType.ProcessingInstruction:
  368. writer.WriteProcessingInstruction (navigator.Name, navigator.Value);
  369. break;
  370. case XPathNodeType.Text:
  371. writer.WriteString (navigator.Value);
  372. break;
  373. case XPathNodeType.SignificantWhitespace:
  374. case XPathNodeType.Whitespace:
  375. writer.WriteWhitespace (navigator.Value);
  376. break;
  377. }
  378. }
  379. // Extension Objects
  380. internal delegate object ExtensionFunction(object[] args);
  381. private struct ExtensionFunctionHolder {
  382. public libxsltXPathFunction func;
  383. public string ns, name;
  384. }
  385. // Wraps an ExtensionFunction into a function that is callable from the libxslt library.
  386. private unsafe class ExtensionFunctionWrapper {
  387. private readonly ExtensionFunction func;
  388. public ExtensionFunctionWrapper(ExtensionFunction func) {
  389. if ((object)func == null) throw new ArgumentNullException("func");
  390. this.func = func;
  391. }
  392. public unsafe void Function(IntPtr xpath_ctxt, int nargs) {
  393. // Convert XPath arguments into "managed" arguments
  394. System.Collections.ArrayList args = new System.Collections.ArrayList();
  395. for (int i = 0; i < nargs; i++) {
  396. xpathobject* aptr = valuePop(xpath_ctxt);
  397. if (aptr->type == 2) // Booleans
  398. args.Add( xmlXPathCastToBoolean(aptr) == 0 ? false : true );
  399. else if (aptr->type == 3) // Doubles
  400. args.Add( xmlXPathCastToNumber(aptr));
  401. else if (aptr->type == 4) // Strings
  402. args.Add( xmlXPathCastToString(aptr));
  403. else if (aptr->type == 1 && aptr->nodesetptr != null) { // Node Sets ==> ArrayList of strings
  404. System.Collections.ArrayList a = new System.Collections.ArrayList();
  405. for (int ni = 0; ni < aptr->nodesetptr->count; ni++) {
  406. xpathobject *n = xmlXPathNewNodeSet(aptr->nodesetptr->nodes[ni]);
  407. valuePush(xpath_ctxt, n);
  408. xmlXPathStringFunction(xpath_ctxt, 1);
  409. a.Add(xmlXPathCastToString(valuePop(xpath_ctxt)));
  410. xmlXPathFreeObject(n);
  411. }
  412. args.Add(a);
  413. } else { // Anything else => string
  414. valuePush(xpath_ctxt, aptr);
  415. xmlXPathStringFunction(xpath_ctxt, 1);
  416. args.Add(xmlXPathCastToString(valuePop(xpath_ctxt)));
  417. }
  418. xmlXPathFreeObject(aptr);
  419. }
  420. args.Reverse();
  421. object ret = func(args.ToArray());
  422. // Convert the result back to an XPath object
  423. if (ret == null) // null => ""
  424. valuePush(xpath_ctxt, xmlXPathNewCString(""));
  425. else if (ret is bool) // Booleans
  426. valuePush(xpath_ctxt, xmlXPathNewBoolean((bool)ret ? 1 : 0));
  427. else if (ret is int || ret is long || ret is double || ret is float || ret is decimal)
  428. // Numbers
  429. valuePush(xpath_ctxt, xmlXPathNewFloat((double)ret));
  430. else // Everything else => String
  431. valuePush(xpath_ctxt, xmlXPathNewCString(ret.ToString()));
  432. }
  433. }
  434. // Provides a delegate for calling a late-bound method of a type with a given name.
  435. // Determines method based on types of arguments.
  436. private class ReflectedExtensionFunction {
  437. System.Type type;
  438. object src;
  439. string methodname;
  440. public ReflectedExtensionFunction(System.Type type, object src, string methodname) { this.type = type; this.src = src; this.methodname = methodname; }
  441. public object Function(object[] args) {
  442. // Construct arg type array, and a stringified version in case of problem
  443. System.Type[] argtypes = new System.Type[args.Length];
  444. string argtypelist = null;
  445. for (int i = 0; i < args.Length; i++) {
  446. argtypes[i] = (args[i] == null ? typeof(object) : args[i].GetType() );
  447. if (argtypelist != null) argtypelist += ", ";
  448. argtypelist += argtypes[i].FullName;
  449. }
  450. if (argtypelist == null) argtypelist = "";
  451. // Find the method
  452. System.Reflection.MethodInfo mi = type.GetMethod(methodname, (src == null ? BF.Static : BF.Instance | BF.Static) | BF.Public, null, argtypes, null);
  453. // No method?
  454. if (mi == null) throw new XmlException("No applicable function for " + methodname + " takes (" + argtypelist + ")");
  455. if (!mi.IsStatic && src == null) throw new XmlException("Attempt to call static method without instantiated extension object.");
  456. // Invoke
  457. return mi.Invoke(src, args);
  458. }
  459. }
  460. // Special Mono-specific class that allows static methods of a type to
  461. // be bound without needing an instance of that type. Useful for
  462. // registering System.Math functions, for example.
  463. // Usage: args.AddExtensionObject( new XslTransform.UseStaticMethods(typeof(thetype)) );
  464. public sealed class UseStaticMethods {
  465. public readonly System.Type Type;
  466. public UseStaticMethods(System.Type Type) { this.Type = Type; }
  467. }
  468. #endregion
  469. #region Calls to external libraries
  470. // libxslt
  471. [DllImport ("xslt")]
  472. static extern IntPtr xsltParseStylesheetFile (string filename);
  473. [DllImport ("xslt")]
  474. static extern IntPtr xsltParseStylesheetDoc (IntPtr docPtr);
  475. [DllImport ("xslt")]
  476. static extern IntPtr xsltApplyStylesheet (IntPtr stylePtr, IntPtr DocPtr, string[] argPtr);
  477. [DllImport ("xslt")]
  478. static extern int xsltSaveResultToString (ref IntPtr stringPtr, ref int stringLen,
  479. IntPtr docPtr, IntPtr stylePtr);
  480. [DllImport ("xslt")]
  481. static extern int xsltSaveResultToFilename (string URI, IntPtr doc, IntPtr styleSheet, int compression);
  482. [DllImport ("xslt")]
  483. static extern void xsltCleanupGlobals ();
  484. [DllImport ("xslt")]
  485. static extern void xsltFreeStylesheet (IntPtr cur);
  486. // libxml2
  487. [DllImport ("xml2")]
  488. static extern IntPtr xmlNewDoc (string version);
  489. [DllImport ("xml2")]
  490. static extern int xmlSaveFile (string filename, IntPtr cur);
  491. [DllImport ("xml2")]
  492. static extern IntPtr xmlParseFile (string filename);
  493. [DllImport ("xml2")]
  494. static extern IntPtr xmlParseDoc (string document);
  495. [DllImport ("xml2")]
  496. static extern void xmlFreeDoc (IntPtr doc);
  497. [DllImport ("xml2")]
  498. static extern void xmlCleanupParser ();
  499. [DllImport ("xml2")]
  500. static extern void xmlDocDumpMemory (IntPtr doc, ref IntPtr mem, ref int size);
  501. [DllImport ("xml2")]
  502. static extern void xmlFree (IntPtr data);
  503. // Functions and structures for extension objects
  504. [DllImport ("xslt")]
  505. static extern IntPtr xsltNewTransformContext (IntPtr style, IntPtr doc);
  506. [DllImport ("xslt")]
  507. static extern void xsltFreeTransformContext (IntPtr context);
  508. [DllImport ("xslt")]
  509. static extern IntPtr xsltApplyStylesheetUser (IntPtr stylePtr, IntPtr DocPtr, string[] argPtr, string output, IntPtr profile, IntPtr context);
  510. [DllImport ("xslt")]
  511. static extern int xsltRegisterExtFunction (IntPtr context, string name, string uri, libxsltXPathFunction function);
  512. [DllImport ("xml2")]
  513. unsafe static extern xpathobject* valuePop (IntPtr context);
  514. [DllImport ("xml2")]
  515. unsafe static extern void valuePush (IntPtr context, xpathobject* data);
  516. [DllImport("xml2")]
  517. unsafe static extern void xmlXPathFreeObject(xpathobject* obj);
  518. [DllImport("xml2")]
  519. unsafe static extern xpathobject* xmlXPathNewCString(string str);
  520. [DllImport("xml2")]
  521. unsafe static extern xpathobject* xmlXPathNewFloat(double val);
  522. [DllImport("xml2")]
  523. unsafe static extern xpathobject* xmlXPathNewBoolean(int val);
  524. [DllImport("xml2")]
  525. unsafe static extern xpathobject* xmlXPathNewNodeSet(IntPtr nodeptr);
  526. [DllImport("xml2")]
  527. unsafe static extern int xmlXPathCastToBoolean(xpathobject* val);
  528. [DllImport("xml2")]
  529. unsafe static extern double xmlXPathCastToNumber(xpathobject* val);
  530. [DllImport("xml2")]
  531. unsafe static extern string xmlXPathCastToString(xpathobject* val);
  532. [DllImport("xml2")]
  533. static extern void xmlXPathStringFunction(IntPtr context, int nargs);
  534. private delegate void libxsltXPathFunction(IntPtr xpath_ctxt, int nargs);
  535. private struct xpathobject {
  536. public int type;
  537. public xmlnodelist* nodesetptr;
  538. }
  539. private struct xmlnodelist {
  540. public int count;
  541. public int allocated;
  542. public IntPtr* nodes;
  543. }
  544. #endregion
  545. // This classes just makes the base class use 'encoding="utf-8"'
  546. class UTF8StringWriter : StringWriter
  547. {
  548. static Encoding encoding = new UTF8Encoding (false);
  549. public override Encoding Encoding {
  550. get {
  551. return encoding;
  552. }
  553. }
  554. }
  555. }
  556. }