PageRenderTime 28ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/QueryMachine.XQuery/Core.cs

#
C# | 1532 lines | 1413 code | 112 blank | 7 comment | 388 complexity | b4e0c6f572a41f05796ee015d639231a MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. // Copyright (c) 2009-2011, Semyon A. Chertkov (semyonc@gmail.com)
  2. // All rights reserved.
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // any later version.
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Text;
  11. using System.IO;
  12. using System.Diagnostics;
  13. using System.Globalization;
  14. using System.Xml;
  15. using System.Xml.Schema;
  16. using System.Xml.XPath;
  17. using System.Threading.Tasks;
  18. using DataEngine.CoreServices;
  19. using DataEngine.XQuery.Util;
  20. using DataEngine.XQuery.MS;
  21. namespace DataEngine.XQuery
  22. {
  23. public partial class ID
  24. {
  25. public static readonly object DynExecuteExpr = ATOM.Create("dyn_execute");
  26. public static readonly object Doc = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "doc" }, true);
  27. public static readonly object Root = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "root" }, true);
  28. public static readonly object Position = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "position" }, true);
  29. public static readonly object Last = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "last" }, true);
  30. public static readonly object ContextNode = ATOM.Create("context-node");
  31. public static readonly object BooleanValue = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "boolean" }, true);
  32. public static readonly object True = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "true" }, true);
  33. public static readonly object False = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "false" }, true);
  34. public static readonly object Not = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "not" }, true);
  35. public static readonly object String = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "string" }, true);
  36. public static readonly object Number = ATOM.Create(XmlReservedNs.NsXQueryFunc, new string[] { "number" }, true);
  37. public static readonly object DynCreateDocument = ATOM.Create("dyn_root");
  38. public static readonly object DynCreateElement = ATOM.Create("dyn_element");
  39. public static readonly object DynCreateAttribute = ATOM.Create("dyn_attribute");
  40. public static readonly object DynCreateCData = ATOM.Create("dyn_cdata");
  41. public static readonly object DynCreateText = ATOM.Create("dyn_text");
  42. public static readonly object DynCreateComment = ATOM.Create("dyn_comment");
  43. public static readonly object DynCreatePi = ATOM.Create("dyn_pi");
  44. public static readonly object DynZeroOrOne = ATOM.Create("dyn_zero_or_one");
  45. public static readonly object CreateBuilder = ATOM.Create("create-builder");
  46. public static readonly object CreateNavigator = ATOM.Create("create-navigator");
  47. public static readonly object WriteBeginElement = ATOM.Create("begin-element");
  48. public static readonly object WriteEndElement = ATOM.Create("end-element");
  49. public static readonly object WriteBeginAttribute = ATOM.Create("begin-attribute");
  50. public static readonly object WriteEndAttribute = ATOM.Create("end-attribute");
  51. public static readonly object WriteRaw = ATOM.Create("write-raw");
  52. public static readonly object WriteNode = ATOM.Create("write-node");
  53. public static readonly object WriteComment = ATOM.Create("write-comment");
  54. public static readonly object WritePi = ATOM.Create("write-pi");
  55. public static readonly object WriteString = ATOM.Create("write-string");
  56. public static readonly object WriteWhitespace = ATOM.Create("write-ws");
  57. public static readonly object WriteCdata = ATOM.Create("write-cdata");
  58. public static readonly object Atomize = ATOM.Create("atomize");
  59. public static readonly object AtomizeX = ATOM.Create("atomize_x");
  60. public static readonly object AtomizeBody = ATOM.Create("atomize#");
  61. public static readonly object NodeValue = ATOM.Create("node");
  62. public static readonly object NodeValueX = ATOM.Create("node_x");
  63. public static readonly object NodeValueBody = ATOM.Create("node#");
  64. public static readonly object FormatValue = ATOM.Create("format-value");
  65. public static readonly object InstanceOf = ATOM.Create("instance-of");
  66. public static readonly object CastTo = ATOM.Create("cast-to");
  67. public static readonly object CastToItem = ATOM.Create("cast-to-item");
  68. public static readonly object Castable = ATOM.Create("castable");
  69. public static readonly object TreatAs = ATOM.Create("treat-as");
  70. public static readonly object CastArg = ATOM.Create("cast-arg");
  71. public static readonly object GeneralEQ = ATOM.Create("general-eq");
  72. public static readonly object GeneralNE = ATOM.Create("general-ne");
  73. public static readonly object GeneralLT = ATOM.Create("general-lt");
  74. public static readonly object GeneralGT = ATOM.Create("general-gt");
  75. public static readonly object GeneralGE = ATOM.Create("general-ge");
  76. public static readonly object GeneralLE = ATOM.Create("general-le");
  77. public static readonly object Some = ATOM.Create("some");
  78. public static readonly object Every = ATOM.Create("every");
  79. public static readonly object SameNode = ATOM.Create("is-same-node");
  80. public static readonly object PrecedingNode = ATOM.Create("is-preceding-node");
  81. public static readonly object FollowingNode = ATOM.Create("is-following-node");
  82. public static readonly object Range = ATOM.Create("range");
  83. public static readonly object Except = ATOM.Create("except");
  84. public static readonly object Intersect = ATOM.Create("intersect");
  85. public static readonly object Union = ATOM.Create("union");
  86. public static readonly object Context = ATOM.Create("$context");
  87. public static readonly object Seq = ATOM.Create("$seq");
  88. public static readonly object IsUnknown = ATOM.Create("is-unknown");
  89. public static readonly object Par = ATOM.Create("par");
  90. public static readonly object ExactlyOne = ATOM.Create("dyn-exactly-one");
  91. public static readonly object RaiseUnknown = ATOM.Create("raise-unknown");
  92. public static readonly object Validate = ATOM.Create("validate");
  93. public static readonly object CastToNumber1 = ATOM.Create("cast-to-number1");
  94. public static readonly object CastToNumber2 = ATOM.Create("cast-to-number2");
  95. public static readonly object CastToNumber3 = ATOM.Create("cast-to-number3");
  96. }
  97. public static class Core
  98. {
  99. static Core()
  100. {
  101. GlobalSymbols.DefineStaticOperator(ID.CreateNavigator, typeof(Core), "CreateNavigator");
  102. GlobalSymbols.DefineStaticOperator(ID.DynExecuteExpr, typeof(Core), "DynExecuteExpr");
  103. GlobalSymbols.DefineStaticOperator(ID.DynCreateDocument, typeof(Core), "DynCreateDocument");
  104. GlobalSymbols.DefineStaticOperator(ID.DynCreateElement, typeof(Core), "DynCreateElement");
  105. GlobalSymbols.DefineStaticOperator(ID.DynCreateAttribute, typeof(Core), "DynCreateAttribute");
  106. GlobalSymbols.DefineStaticOperator(ID.DynCreateCData, typeof(Core), "DynCreateCData");
  107. GlobalSymbols.DefineStaticOperator(ID.DynCreateText, typeof(Core), "DynCreateText");
  108. GlobalSymbols.DefineStaticOperator(ID.DynCreateComment, typeof(Core), "DynCreateComment");
  109. GlobalSymbols.DefineStaticOperator(ID.DynCreatePi, typeof(Core), "DynCreatePi");
  110. GlobalSymbols.DefineStaticOperator(ID.CreateBuilder, typeof(Core), "CreateBuilder");
  111. GlobalSymbols.DefineStaticOperator(ID.WriteBeginElement, typeof(Core), "BeginElement");
  112. GlobalSymbols.DefineStaticOperator(ID.WriteEndElement, typeof(Core), "EndElement");
  113. GlobalSymbols.DefineStaticOperator(ID.WriteBeginAttribute, typeof(Core), "BeginAttribute");
  114. GlobalSymbols.DefineStaticOperator(ID.WriteEndAttribute, typeof(Core), "EndAttribute");
  115. GlobalSymbols.DefineStaticOperator(ID.WriteComment, typeof(Core), "CreateComment");
  116. GlobalSymbols.DefineStaticOperator(ID.WritePi, typeof(Core), "CreatePi");
  117. GlobalSymbols.DefineStaticOperator(ID.WriteCdata, typeof(Core), "CreateCdata");
  118. GlobalSymbols.DefineStaticOperator(ID.WriteNode, typeof(Core), "WriteNode");
  119. GlobalSymbols.DefineStaticOperator(ID.WriteString, typeof(Core), "WriteString");
  120. GlobalSymbols.DefineStaticOperator(ID.WriteWhitespace, typeof(Core), "WriteWhitespace");
  121. GlobalSymbols.DefineStaticOperator(ID.FormatValue, typeof(Core), "FormatValue");
  122. GlobalSymbols.DefineStaticOperator(ID.AtomizeBody, typeof(Core), "Atomize");
  123. GlobalSymbols.DefineStaticOperator(ID.NodeValueBody, typeof(Core), "NodeValue");
  124. GlobalSymbols.DefineStaticOperator(ID.ContextNode, typeof(Core), "ContextNode");
  125. GlobalSymbols.DefineStaticOperator(ID.Seq, typeof(Core), "CreateSequence");
  126. GlobalSymbols.DefineStaticOperator(ID.IsUnknown, typeof(Core), "IsUnknown");
  127. GlobalSymbols.DefineStaticOperator(ID.RaiseUnknown, typeof(Core), "RaiseUnknown");
  128. GlobalSymbols.DefineStaticOperator(ID.InstanceOf, typeof(Core), "InstanceOf");
  129. GlobalSymbols.DefineStaticOperator(ID.Castable, typeof(Core), "Castable");
  130. GlobalSymbols.DefineStaticOperator(ID.CastTo, typeof(Core), "CastTo");
  131. GlobalSymbols.DefineStaticOperator(ID.CastToItem, typeof(Core), "CastToItem");
  132. GlobalSymbols.DefineStaticOperator(ID.TreatAs, typeof(Core), "TreatAs");
  133. GlobalSymbols.DefineStaticOperator(ID.CastArg, typeof(Core), "CastArg");
  134. GlobalSymbols.DefineStaticOperator(ID.GeneralEQ, typeof(Core), "GeneralEQ");
  135. GlobalSymbols.DefineStaticOperator(ID.GeneralNE, typeof(Core), "GeneralNE");
  136. GlobalSymbols.DefineStaticOperator(ID.GeneralGT, typeof(Core), "GeneralGT");
  137. GlobalSymbols.DefineStaticOperator(ID.GeneralGE, typeof(Core), "GeneralGE");
  138. GlobalSymbols.DefineStaticOperator(ID.GeneralLT, typeof(Core), "GeneralLT");
  139. GlobalSymbols.DefineStaticOperator(ID.GeneralLE, typeof(Core), "GeneralLE");
  140. GlobalSymbols.DefineStaticOperator(ID.Some, typeof(Core), "Some");
  141. GlobalSymbols.DefineStaticOperator(ID.Every, typeof(Core), "Every");
  142. GlobalSymbols.DefineStaticOperator(ID.SameNode, typeof(Core), "SameNode");
  143. GlobalSymbols.DefineStaticOperator(ID.PrecedingNode, typeof(Core), "PrecedingNode");
  144. GlobalSymbols.DefineStaticOperator(ID.FollowingNode, typeof(Core), "FollowingNode");
  145. GlobalSymbols.DefineStaticOperator(ID.Range, typeof(Core), "GetRange");
  146. GlobalSymbols.DefineStaticOperator(ID.Except, typeof(Core), "Except");
  147. GlobalSymbols.DefineStaticOperator(ID.Intersect, typeof(Core), "Intersect");
  148. GlobalSymbols.DefineStaticOperator(ID.Union, typeof(Core), "Union");
  149. GlobalSymbols.DefineStaticOperator(ID.Validate, typeof(Core), "Validate");
  150. GlobalSymbols.DefineStaticOperator(ID.CastToNumber1, typeof(Core), "CastToNumber1");
  151. GlobalSymbols.DefineStaticOperator(ID.CastToNumber2, typeof(Core), "CastToNumber2");
  152. GlobalSymbols.DefineStaticOperator(ID.CastToNumber3, typeof(Core), "CastToNumber3");
  153. XQueryFunctionTable.Register(ID.Position, typeof(Core), "CurrentPosition");
  154. XQueryFunctionTable.Register(ID.Last, typeof(Core), "LastPosition");
  155. XQueryFunctionTable.Register(ID.Doc, typeof(Core), "GetDocument");
  156. XQueryFunctionTable.Register(ID.Root, typeof(Core), "GetRoot");
  157. XQueryFunctionTable.Register(ID.BooleanValue, typeof(Core), "BooleanValue");
  158. XQueryFunctionTable.Register(ID.True, typeof(Core), "True");
  159. XQueryFunctionTable.Register(ID.False, typeof(Core), "False");
  160. XQueryFunctionTable.Register(ID.Not, typeof(Core), "Not");
  161. XQueryFunctionTable.Register(ID.Number, typeof(Core), "Number");
  162. XQueryFunctionTable.Register(ID.String, typeof(Core), "StringValue");
  163. ValueProxy.AddFactory(
  164. new ValueProxyFactory[] {
  165. new DateTimeValue.ProxyFactory(),
  166. new DateValue.ProxyFactory(),
  167. new TimeValue.ProxyFactory(),
  168. new DurationValue.ProxyFactory(),
  169. new YearMonthDurationValue.ProxyFactory(),
  170. new DayTimeDurationValue.ProxyFactory()
  171. });
  172. GlobalSymbols.Defmacro(ID.Atomize, "(x)",
  173. @"(list 'let (list (list 'y (list 'atomize# x)))
  174. (list 'cond (list (list 'is-unknown 'y) (list 'trap 'unknown)) (list 't 'y)))");
  175. GlobalSymbols.Defmacro(ID.AtomizeX, "(x)",
  176. @"(list 'let (list (list 'y (list 'atomize# x)))
  177. (list 'cond (list (list 'is-unknown 'y) (list 'raise-unknown)) (list 't 'y)))");
  178. GlobalSymbols.Defmacro(ID.NodeValue, "(x)",
  179. @"(list 'cast (list 'let (list (list 'y (list 'node# x)))
  180. (list 'cond (list (list 'is-unknown 'y) (list 'trap 'unknown)) (list 't 'y))) node#type)");
  181. GlobalSymbols.Defmacro(ID.NodeValueX, "(x)",
  182. @"(list 'cast (list 'let (list (list 'y (list 'node# x)))
  183. (list 'cond (list (list 'is-unknown 'y) (list 'raise-unknown)) (list 't 'y))) node#type)");
  184. GlobalSymbols.Defmacro(ID.DynZeroOrOne, "(x)",
  185. @"(list 'let (list (list 'y x))
  186. (list 'cond (list (list 'is-unknown 'y) (list 'trap 'unknown)) (list 't 'y)))");
  187. GlobalSymbols.Defmacro(ID.Par, "(x)", "x");
  188. GlobalSymbols.Defmacro(ID.ExactlyOne, "(x)",
  189. "(list 'if (list 'is-unknown x) (list 'raise-unknown) x)");
  190. }
  191. internal static void Init()
  192. {
  193. }
  194. public static bool IsUnknown(object value)
  195. {
  196. return value == Undefined.Value;
  197. }
  198. public static void RaiseUnknown()
  199. {
  200. throw new XQueryException(Properties.Resources.XPTY0004, "empty-sequence()", "item()");
  201. }
  202. private static QNameValue GetQualifiedName(object name, XmlNamespaceManager nsmgr, string defaultNamespace)
  203. {
  204. if (name is QNameValue)
  205. return (QNameValue)name;
  206. else if (name is String || name is UntypedAtomic)
  207. return QNameValue.Parse(name.ToString(), nsmgr, defaultNamespace);
  208. else
  209. throw new XQueryException(Properties.Resources.XPST0004,
  210. "xs:string | xs:untypedAtomic | xs:QName");
  211. }
  212. private static XQueryDocumentBuilder GetBuilder(object builder)
  213. {
  214. return builder as XQueryDocumentBuilder;
  215. }
  216. [XQuerySignature("doc", Return=XmlTypeCode.Node, Cardinality=XmlTypeCardinality.ZeroOrOne)]
  217. public static object GetDocument([Implict] Executive executive,
  218. [XQueryParameter(XmlTypeCode.String, Cardinality=XmlTypeCardinality.ZeroOrOne)] object name)
  219. {
  220. XQueryContext context = (XQueryContext)executive.Owner;
  221. if (name == Undefined.Value)
  222. return Undefined.Value;
  223. string fileName;
  224. try
  225. {
  226. fileName = context.GetFileName((string)name);
  227. if (fileName == null)
  228. throw new XQueryException(Properties.Resources.FileNotFound, name);
  229. }
  230. catch (ArgumentException ex)
  231. {
  232. throw new XQueryException(ex.Message, ex);
  233. }
  234. IXPathNavigable doc = context.OpenDocument(fileName);
  235. return doc.CreateNavigator();
  236. }
  237. public static XQueryNodeIterator CreateSequence(object value)
  238. {
  239. return XQueryNodeIterator.Create(value);
  240. }
  241. public static object DynExecuteExpr(object obj, IContextProvider provider, object[] args, MemoryPool pool)
  242. {
  243. XQueryExprBase expr = (XQueryExprBase)obj;
  244. return expr.Execute(provider, args, pool);
  245. }
  246. public static XPathItem ContextNode(IContextProvider provider)
  247. {
  248. XPathItem item = provider.Context;
  249. if (item == null)
  250. throw new XQueryException(Properties.Resources.XPDY0002);
  251. return item;
  252. }
  253. public static int CurrentPosition(IContextProvider provider)
  254. {
  255. return provider.CurrentPosition;
  256. }
  257. public static int LastPosition(IContextProvider provider)
  258. {
  259. return provider.LastPosition;
  260. }
  261. public static object DynCreateDocument([Implict] Executive executive, object body)
  262. {
  263. XQueryContext context = (XQueryContext)executive.Owner;
  264. XQueryDocument doc = context.CreateDocument();
  265. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  266. builder.WriteStartDocument();
  267. if (body != null)
  268. WriteNode(executive, builder, body);
  269. return doc.CreateNavigator();
  270. }
  271. public static object DynCreateElement([Implict] Executive executive, QNameValue name, object body)
  272. {
  273. XQueryContext context = (XQueryContext)executive.Owner;
  274. XQueryDocument doc = context.CreateDocument();
  275. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  276. builder.WriteStartElement(name.Prefix, name.LocalName, name.NamespaceUri);
  277. if (body != null)
  278. WriteNode(executive, builder, body);
  279. builder.WriteEndElement();
  280. return doc.CreateNavigator();
  281. }
  282. public static object DynCreateElement([Implict] Executive executive, object name, XmlNamespaceManager nsmgr, object body)
  283. {
  284. XQueryContext context = (XQueryContext)executive.Owner;
  285. XQueryDocument doc = context.CreateDocument();
  286. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  287. QNameValue qname = GetQualifiedName(name, nsmgr, nsmgr.DefaultNamespace);
  288. builder.WriteStartElement(qname.Prefix, qname.LocalName, qname.NamespaceUri);
  289. if (body != null)
  290. WriteNode(executive, builder, body);
  291. builder.WriteEndElement();
  292. return doc.CreateNavigator();
  293. }
  294. public static object DynCreateAttribute([Implict] Executive executive, QNameValue name, object value)
  295. {
  296. XQueryContext context = (XQueryContext)executive.Owner;
  297. XQueryDocument doc = context.CreateDocument();
  298. doc.flags = XQueryDocument.DYN_DOCUMENT;
  299. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  300. if (name.Prefix == "xmlns" || (name.Prefix == "" && name.LocalName == "xmlns"))
  301. throw new XQueryException(Properties.Resources.XQDY0044);
  302. builder.WriteStartElement("dummy");
  303. builder.WriteStartAttribute(name.Prefix, name.LocalName, name.NamespaceUri);
  304. string text = value == Undefined.Value ? "" : (string)value;
  305. builder.WriteString(text);
  306. builder.WriteEndAttribute();
  307. builder.WriteEndElement();
  308. XPathNavigator nav = doc.CreateNavigator();
  309. return new NodeIterator(XPathFactory.DynAttributeIterator(nav));
  310. }
  311. public static object DynCreateAttribute([Implict] Executive executive, object name, XmlNamespaceManager nsmgr, object value)
  312. {
  313. XQueryContext context = (XQueryContext)executive.Owner;
  314. XQueryDocument doc = context.CreateDocument();
  315. doc.flags = XQueryDocument.DYN_DOCUMENT;
  316. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  317. QNameValue qname = GetQualifiedName(name, nsmgr, "");
  318. if (qname.Prefix == "xmlns" || (qname.Prefix == "" && qname.LocalName == "xmlns"))
  319. throw new XQueryException(Properties.Resources.XQDY0044);
  320. builder.WriteStartElement("dummy");
  321. builder.WriteStartAttribute(qname.Prefix, qname.LocalName, qname.NamespaceUri);
  322. string text = value == Undefined.Value ? "" : (string)value;
  323. builder.WriteString(text);
  324. builder.WriteEndAttribute();
  325. builder.WriteEndElement();
  326. XPathNavigator nav = doc.CreateNavigator();
  327. return new NodeIterator(XPathFactory.DynAttributeIterator(nav));
  328. }
  329. public static object DynCreateCData([Implict] Executive executive, object value)
  330. {
  331. if (value == Undefined.Value)
  332. return Undefined.Value;
  333. XQueryContext context = (XQueryContext)executive.Owner;
  334. XQueryDocument doc = context.CreateDocument();
  335. doc.flags = XQueryDocument.DYN_DOCUMENT;
  336. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  337. builder.WriteString((string)value);
  338. return doc.CreateNavigator();
  339. }
  340. public static object DynCreateText([Implict] Executive executive, object value)
  341. {
  342. if (value == Undefined.Value)
  343. return Undefined.Value;
  344. XQueryContext context = (XQueryContext)executive.Owner;
  345. XQueryDocument doc = context.CreateDocument();
  346. doc.flags = XQueryDocument.DYN_DOCUMENT;
  347. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  348. builder.WriteString((string)value);
  349. return doc.CreateNavigator();
  350. }
  351. public static object DynCreateComment([Implict] Executive executive, object value)
  352. {
  353. XQueryContext context = (XQueryContext)executive.Owner;
  354. XQueryDocument doc = context.CreateDocument();
  355. doc.flags = XQueryDocument.DYN_DOCUMENT;
  356. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  357. string text = value == Undefined.Value ? "" : NormalizeStringValue((string)value, false, true);
  358. if (text.EndsWith("-") || text.Contains("--"))
  359. throw new XQueryException(Properties.Resources.XQDY0072);
  360. builder.WriteComment(text);
  361. return doc.CreateNavigator();
  362. }
  363. public static object DynCreatePi([Implict] Executive executive, object name, object value)
  364. {
  365. if (name == Undefined.Value)
  366. throw new XQueryException(Properties.Resources.XPTY0004, "()", "xs:string | xs:untypedAtomic");
  367. string ncname = (string)name;
  368. if (String.Compare(ncname, "xml", true) == 0)
  369. throw new XQueryException(Properties.Resources.XQDY0064);
  370. string text = value == Undefined.Value ? "" : NormalizeStringValue(value.ToString(), false, true).Trim();
  371. if (text.Contains("?>"))
  372. throw new XQueryException(Properties.Resources.XQDY0026);
  373. XQueryContext context = (XQueryContext)executive.Owner;
  374. XQueryDocument doc = context.CreateDocument();
  375. doc.flags = XQueryDocument.DYN_DOCUMENT;
  376. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  377. try
  378. {
  379. builder.WriteProcessingInstruction(XmlConvert.VerifyNCName(ncname), text);
  380. }
  381. catch (XmlException)
  382. {
  383. throw new XQueryException(Properties.Resources.FORG0001, name, "xs:NCName");
  384. }
  385. return doc.CreateNavigator();
  386. }
  387. public static object CreateBuilder([Implict] Executive executive)
  388. {
  389. XQueryContext context = (XQueryContext)executive.Owner;
  390. XQueryDocument doc = context.CreateDocument();
  391. XQueryDocumentBuilder builder = new XQueryDocumentBuilder(doc);
  392. builder.NamespaceInheritanceMode = context.NamespaceInheritanceMode;
  393. return builder;
  394. }
  395. public static object CreateNavigator(object o)
  396. {
  397. XQueryDocumentBuilder builder = GetBuilder(o);
  398. return builder.Document.CreateNavigator();
  399. }
  400. public static object BeginElement([Implict] Executive executive, object o, QNameValue name)
  401. {
  402. XQueryContext context = (XQueryContext)executive.Owner;
  403. XQueryDocumentBuilder builder = GetBuilder(o);
  404. builder.WriteStartElement(name.Prefix, name.LocalName, name.NamespaceUri);
  405. return builder;
  406. }
  407. public static object EndElement(object o)
  408. {
  409. XQueryDocumentBuilder builder = GetBuilder(o);
  410. builder.WriteEndElement();
  411. return builder;
  412. }
  413. public static object BeginAttribute([Implict] Executive executive, object o, QNameValue name)
  414. {
  415. XQueryContext context = (XQueryContext)executive.Owner;
  416. XQueryDocumentBuilder builder = GetBuilder(o);
  417. builder.WriteStartAttribute(name.Prefix, name.LocalName, name.NamespaceUri);
  418. return builder;
  419. }
  420. public static object EndAttribute(object o)
  421. {
  422. XQueryDocumentBuilder builder = GetBuilder(o);
  423. builder.WriteEndAttribute();
  424. return builder;
  425. }
  426. public static object CreateComment(object o, string text)
  427. {
  428. XQueryDocumentBuilder builder = GetBuilder(o);
  429. builder.WriteComment(text);
  430. return builder;
  431. }
  432. public static object CreatePi(object o, string name, string text)
  433. {
  434. XQueryDocumentBuilder builder = GetBuilder(o);
  435. builder.WriteProcessingInstruction(name, text);
  436. return builder;
  437. }
  438. public static string NormalizeStringValue(string value, bool attr, bool raiseException)
  439. {
  440. StringBuilder sb = new StringBuilder(value);
  441. int i = 0;
  442. while (i < sb.Length)
  443. {
  444. switch (sb[i])
  445. {
  446. case '\t':
  447. if (attr)
  448. sb[i] = ' ';
  449. i++;
  450. break;
  451. case '\n':
  452. if (i < sb.Length - 1 && sb[i + 1] == '\r')
  453. sb.Remove(i + 1, 1);
  454. if (attr)
  455. sb[i] = ' ';
  456. i++;
  457. break;
  458. case '\r':
  459. if (i < sb.Length - 1 && sb[i + 1] == '\n')
  460. sb.Remove(i + 1, 1);
  461. if (attr)
  462. sb[i] = ' ';
  463. else
  464. sb[i] = '\n';
  465. i++;
  466. break;
  467. case '&':
  468. bool process = false;
  469. for (int j = i + 1; j < sb.Length; j++)
  470. if (sb[j] == ';')
  471. {
  472. string entity = sb.ToString(i + 1, j - i - 1);
  473. string entity_value = null;
  474. if (entity.StartsWith("#"))
  475. {
  476. int n;
  477. if (entity.StartsWith("#x"))
  478. {
  479. if (entity.Length > 2 && Int32.TryParse(entity.Substring(2, entity.Length - 2),
  480. System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out n))
  481. entity_value = Convert.ToString(Convert.ToChar(n));
  482. }
  483. else
  484. {
  485. if (entity.Length > 1 && Int32.TryParse(entity.Substring(1, entity.Length - 1), out n))
  486. entity_value = Convert.ToString(Convert.ToChar(n));
  487. }
  488. }
  489. else if (entity == "gt")
  490. entity_value = ">";
  491. else if (entity == "lt")
  492. entity_value = "<";
  493. else if (entity == "amp")
  494. entity_value = "&";
  495. else if (entity == "quot")
  496. entity_value = "\"";
  497. else if (entity == "apos")
  498. entity_value = "\'";
  499. if (entity_value != null)
  500. {
  501. sb.Remove(i, j - i + 1);
  502. sb.Insert(i, entity_value);
  503. i += entity_value.Length;
  504. process = true;
  505. break;
  506. }
  507. else
  508. if (raiseException)
  509. throw new XQueryException(Properties.Resources.XPST0003, String.Format("Entity reference '&{0};' was not recognized.", entity_value));
  510. }
  511. if (!process)
  512. {
  513. if (raiseException)
  514. throw new XQueryException(Properties.Resources.XPST0003, "Entity reference '&' was not terminated by a semi-colon.");
  515. i++;
  516. }
  517. break;
  518. default:
  519. i++;
  520. break;
  521. }
  522. }
  523. return sb.ToString();
  524. }
  525. public static object WriteString(object o, object text)
  526. {
  527. XQueryDocumentBuilder builder = GetBuilder(o);
  528. if (text != Undefined.Value)
  529. {
  530. string value = NormalizeStringValue((string)text,
  531. builder.WriteState == WriteState.Attribute, false);
  532. if (value != "")
  533. builder.WriteString(value);
  534. }
  535. return builder;
  536. }
  537. public static object WriteWhitespace(object o, string text)
  538. {
  539. XQueryDocumentBuilder builder = GetBuilder(o);
  540. if (text != "")
  541. builder.WriteWhitespace(text);
  542. return builder;
  543. }
  544. public static object CreateCdata(object o, string text)
  545. {
  546. XQueryDocumentBuilder builder = GetBuilder(o);
  547. if (text != "")
  548. builder.WriteString(text);
  549. return builder;
  550. }
  551. public static object FormatValue(object value)
  552. {
  553. StringBuilder sb = new StringBuilder();
  554. if (value is XPathItem)
  555. sb.Append(((XPathItem)value).Value);
  556. else if (value is XQueryNodeIterator)
  557. {
  558. XQueryNodeIterator iter = (XQueryNodeIterator)value;
  559. bool begin = true;
  560. foreach (XPathItem item in iter)
  561. {
  562. if (begin)
  563. begin = false;
  564. else
  565. sb.Append(" ");
  566. sb.Append(item.Value);
  567. }
  568. if (begin)
  569. return Undefined.Value;
  570. }
  571. else
  572. sb.Append(XQueryConvert.ToString(value));
  573. return sb.ToString();
  574. }
  575. public static object WriteNode([Implict] Executive executive, object o, object node)
  576. {
  577. XQueryDocumentBuilder builder = GetBuilder(o);
  578. XQueryContext context = (XQueryContext)executive.Owner;
  579. if (node is XPathNavigator)
  580. {
  581. XPathNavigator nav = (XPathNavigator)node;
  582. if (nav.NodeType == XPathNodeType.Attribute)
  583. {
  584. if (context.ConstructionMode == ElementConstructionMode.Preserve)
  585. builder.SchemaInfo = nav.SchemaInfo;
  586. builder.WriteStartAttribute(nav.Prefix, nav.LocalName, nav.NamespaceURI);
  587. builder.WriteString(nav.Value);
  588. builder.WriteEndAttribute();
  589. builder.SchemaInfo = null;
  590. }
  591. else
  592. {
  593. if (nav.NodeType != XPathNodeType.Text || nav.Value != "")
  594. builder.WriteNode(nav, context.NamespacePreserveMode, context.ConstructionMode);
  595. }
  596. }
  597. else if (node is XPathItem)
  598. {
  599. XPathItem item = (XPathItem)node;
  600. string value = item.Value;
  601. if (value != "")
  602. builder.WriteString(value);
  603. }
  604. else if (node is XQueryNodeIterator)
  605. {
  606. XQueryNodeIterator iter = (XQueryNodeIterator)node;
  607. bool string_flag = false;
  608. foreach (XPathItem item in iter)
  609. {
  610. XPathNavigator nav = item as XPathNavigator;
  611. if (nav != null)
  612. {
  613. if (nav.NodeType == XPathNodeType.Attribute)
  614. {
  615. if (context.ConstructionMode == ElementConstructionMode.Preserve)
  616. builder.SchemaInfo = nav.SchemaInfo;
  617. builder.WriteStartAttribute(nav.Prefix, nav.LocalName, nav.NamespaceURI);
  618. builder.WriteString(nav.Value);
  619. builder.WriteEndAttribute();
  620. builder.SchemaInfo = null;
  621. }
  622. else
  623. {
  624. if (nav.NodeType == XPathNodeType.Text && nav.Value == "")
  625. continue;
  626. builder.WriteNode(nav, context.NamespacePreserveMode, context.ConstructionMode);
  627. }
  628. string_flag = false;
  629. }
  630. else
  631. {
  632. if (string_flag)
  633. builder.WriteString(" ");
  634. builder.WriteString(item.Value);
  635. string_flag = true;
  636. }
  637. }
  638. }
  639. else
  640. if (node != Undefined.Value)
  641. {
  642. string value = XQueryConvert.ToString(node); // !!!
  643. if (value != "")
  644. builder.WriteString(value);
  645. }
  646. return builder;
  647. }
  648. public static bool BooleanValue([XQueryParameter(XmlTypeCode.Item, Cardinality = XmlTypeCardinality.ZeroOrMore)] object value)
  649. {
  650. if (value == null ||
  651. value == DataEngine.CoreServices.Generation.RuntimeOps.False ||
  652. value == Undefined.Value)
  653. return false;
  654. XPathItem item;
  655. XQueryNodeIterator iter = value as XQueryNodeIterator;
  656. if (iter != null)
  657. {
  658. if (!iter.MoveNext())
  659. return false;
  660. item = iter.Current.Clone();
  661. if (item.IsNode)
  662. return true;
  663. if (iter.MoveNext())
  664. throw new XQueryException(Properties.Resources.FORG0006, "fn:boolean()",
  665. new XQuerySequenceType(XmlTypeCode.AnyAtomicType, XmlTypeCardinality.OneOrMore));
  666. }
  667. else
  668. item = value as XPathItem;
  669. if (item != null)
  670. switch (item.XmlType.TypeCode)
  671. {
  672. case XmlTypeCode.Boolean:
  673. return item.ValueAsBoolean;
  674. case XmlTypeCode.String:
  675. case XmlTypeCode.AnyUri:
  676. case XmlTypeCode.UntypedAtomic:
  677. return item.Value != String.Empty;
  678. case XmlTypeCode.Float:
  679. case XmlTypeCode.Double:
  680. return !Double.IsNaN(item.ValueAsDouble) && item.ValueAsDouble != 0.0;
  681. case XmlTypeCode.Decimal:
  682. case XmlTypeCode.Integer:
  683. case XmlTypeCode.NonPositiveInteger:
  684. case XmlTypeCode.NegativeInteger:
  685. case XmlTypeCode.Long:
  686. case XmlTypeCode.Int:
  687. case XmlTypeCode.Short:
  688. case XmlTypeCode.Byte:
  689. case XmlTypeCode.UnsignedInt:
  690. case XmlTypeCode.UnsignedShort:
  691. case XmlTypeCode.UnsignedByte:
  692. case XmlTypeCode.NonNegativeInteger:
  693. case XmlTypeCode.UnsignedLong:
  694. case XmlTypeCode.PositiveInteger:
  695. return (decimal)(item.ValueAs(typeof(Decimal))) != 0;
  696. default:
  697. throw new XQueryException(Properties.Resources.FORG0006, "fn:boolean()",
  698. new XQuerySequenceType(item.XmlType.TypeCode, XmlTypeCardinality.One));
  699. }
  700. else
  701. {
  702. TypeCode typeCode;
  703. IConvertible conv = value as IConvertible;
  704. if (conv != null)
  705. typeCode = conv.GetTypeCode();
  706. else
  707. typeCode = Type.GetTypeCode(value.GetType());
  708. switch (typeCode)
  709. {
  710. case TypeCode.Boolean:
  711. return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
  712. case TypeCode.String:
  713. return Convert.ToString(value, CultureInfo.InvariantCulture) != String.Empty;
  714. case TypeCode.Single:
  715. case TypeCode.Double:
  716. return Convert.ToDouble(value, CultureInfo.InvariantCulture) != 0.0 &&
  717. !Double.IsNaN(Convert.ToDouble(value, CultureInfo.InvariantCulture));
  718. default:
  719. {
  720. if (value is AnyUriValue || value is UntypedAtomic)
  721. return value.ToString() != String.Empty;
  722. if (ValueProxy.IsNumeric(value.GetType()))
  723. return Convert.ToDecimal(value) != 0;
  724. throw new XQueryException(Properties.Resources.FORG0006, "fn:boolean()",
  725. new XQuerySequenceType(value.GetType(), XmlTypeCardinality.One));
  726. }
  727. }
  728. }
  729. }
  730. public static object Atomize(object value)
  731. {
  732. XPathItem item = value as XPathItem;
  733. if (item != null)
  734. return item.TypedValue;
  735. XQueryNodeIterator iter = value as XQueryNodeIterator;
  736. if (iter != null)
  737. {
  738. iter = iter.Clone();
  739. if (!iter.MoveNext())
  740. return Undefined.Value;
  741. object res = iter.Current.TypedValue;
  742. if (iter.MoveNext())
  743. throw new XQueryException(Properties.Resources.MoreThanOneItem);
  744. return res;
  745. }
  746. return value;
  747. }
  748. public static object NodeValue(object value)
  749. {
  750. if (value == Undefined.Value)
  751. return Undefined.Value;
  752. XQueryNodeIterator iter = value as XQueryNodeIterator;
  753. if (iter != null)
  754. {
  755. iter = iter.Clone();
  756. if (!iter.MoveNext())
  757. return Undefined.Value;
  758. XPathItem res = iter.Current.Clone();
  759. if (iter.MoveNext())
  760. throw new XQueryException(Properties.Resources.MoreThanOneItem);
  761. XPathNavigator nav = res as XPathNavigator;
  762. if (nav == null)
  763. throw new XQueryException(Properties.Resources.XPST0004, "node()");
  764. return nav;
  765. }
  766. else
  767. {
  768. XPathNavigator nav = value as XPathNavigator;
  769. if (nav == null)
  770. throw new XQueryException(Properties.Resources.XPST0004, "node()");
  771. return nav.Clone();
  772. }
  773. }
  774. public static bool Some([Implict] Executive executive, object expr)
  775. {
  776. XQueryNodeIterator iter = expr as XQueryNodeIterator;
  777. if (iter != null)
  778. {
  779. while (iter.MoveNext())
  780. if (iter.Current.ValueAsBoolean)
  781. return true;
  782. }
  783. return false;
  784. }
  785. public static bool Every([Implict] Executive executive, object expr)
  786. {
  787. XQueryNodeIterator iter = expr as XQueryNodeIterator;
  788. if (iter != null)
  789. {
  790. while (iter.MoveNext())
  791. if (!iter.Current.ValueAsBoolean)
  792. return false;
  793. }
  794. return true;
  795. }
  796. public static object CastTo([Implict] Executive engine, object value, XQuerySequenceType destType, Type exprType)
  797. {
  798. XQueryContext context = (XQueryContext)engine.Owner;
  799. if (destType == XQuerySequenceType.Item)
  800. return value;
  801. if (value == Undefined.Value)
  802. {
  803. if (destType.Cardinality == XmlTypeCardinality.ZeroOrMore)
  804. return EmptyIterator.Shared;
  805. if (destType.TypeCode != XmlTypeCode.None && destType.Cardinality != XmlTypeCardinality.ZeroOrOne)
  806. throw new XQueryException(Properties.Resources.XPTY0004, "empty-sequence()", destType);
  807. return Undefined.Value;
  808. }
  809. if (destType.Cardinality == XmlTypeCardinality.One ||
  810. destType.Cardinality == XmlTypeCardinality.ZeroOrOne)
  811. {
  812. XPathItem res;
  813. XQueryNodeIterator iter = value as XQueryNodeIterator;
  814. if (iter != null)
  815. {
  816. iter = iter.Clone();
  817. if (!iter.MoveNext())
  818. {
  819. if (destType.TypeCode != XmlTypeCode.None &&
  820. (destType.Cardinality == XmlTypeCardinality.One || destType.Cardinality == XmlTypeCardinality.OneOrMore))
  821. throw new XQueryException(Properties.Resources.XPTY0004, "empty-sequence()", destType);
  822. return Undefined.Value;
  823. }
  824. if (exprType != null && exprType != typeof(System.String))
  825. {
  826. if ((destType.TypeCode == XmlTypeCode.QName && iter.Current.XmlType.TypeCode != XmlTypeCode.QName) ||
  827. (destType.TypeCode == XmlTypeCode.Notation && iter.Current.XmlType.TypeCode != XmlTypeCode.Notation))
  828. throw new XQueryException(Properties.Resources.XPTY0004_CAST, destType);
  829. }
  830. res = iter.Current.ChangeType(destType, context);
  831. if (iter.MoveNext())
  832. throw new XQueryException(Properties.Resources.MoreThanOneItem);
  833. if (destType.IsNode)
  834. return res;
  835. return res.TypedValue;
  836. }
  837. XPathItem item = value as XPathItem;
  838. if (item == null)
  839. item = new XQueryItem(value);
  840. if (exprType != null && exprType != typeof(System.String))
  841. {
  842. if ((destType.TypeCode == XmlTypeCode.QName && item.XmlType.TypeCode != XmlTypeCode.QName) ||
  843. (destType.TypeCode == XmlTypeCode.Notation && item.XmlType.TypeCode != XmlTypeCode.Notation))
  844. throw new XQueryException(Properties.Resources.XPTY0004_CAST, destType);
  845. }
  846. res = item.ChangeType(destType, context);
  847. if (destType.IsNode)
  848. return res;
  849. return res.TypedValue;
  850. }
  851. else
  852. return new NodeIterator(XPathFactory.ConvertIterator(XQueryNodeIterator.Create(value), destType, context));
  853. }
  854. public static object CastArg([Implict] Executive engine, object value, XQuerySequenceType destType)
  855. {
  856. XQueryContext context = (XQueryContext)engine.Owner;
  857. if (destType == XQuerySequenceType.Item)
  858. return value;
  859. if (value == Undefined.Value)
  860. {
  861. if (destType.Cardinality == XmlTypeCardinality.ZeroOrMore)
  862. return EmptyIterator.Shared;
  863. if (destType.TypeCode != XmlTypeCode.None && destType.Cardinality != XmlTypeCardinality.ZeroOrOne)
  864. throw new XQueryException(Properties.Resources.XPTY0004, "empty-sequence()", destType);
  865. return Undefined.Value;
  866. }
  867. if (destType.Cardinality == XmlTypeCardinality.One ||
  868. destType.Cardinality == XmlTypeCardinality.ZeroOrOne)
  869. {
  870. object res;
  871. XQueryNodeIterator iter = value as XQueryNodeIterator;
  872. if (iter != null)
  873. {
  874. iter = iter.Clone();
  875. if (!iter.MoveNext())
  876. {
  877. if (destType.TypeCode != XmlTypeCode.None &&
  878. (destType.Cardinality == XmlTypeCardinality.One || destType.Cardinality == XmlTypeCardinality.OneOrMore))
  879. throw new XQueryException(Properties.Resources.XPTY0004, "empty-sequence()", destType);
  880. return Undefined.Value;
  881. }
  882. if (destType.IsNode)
  883. {
  884. if (!destType.Match(iter.Current, context))
  885. throw new XQueryException(Properties.Resources.XPTY0004,
  886. new XQuerySequenceType(iter.Current.XmlType, XmlTypeCardinality.OneOrMore, null), destType);
  887. res = iter.Current.Clone();
  888. }
  889. else
  890. res = XQueryConvert.ValueAs(iter.Current.TypedValue, destType, context.nameTable, context.NamespaceManager);
  891. if (iter.MoveNext())
  892. throw new XQueryException(Properties.Resources.MoreThanOneItem);
  893. return res;
  894. }
  895. else
  896. {
  897. XPathItem item = value as XPathItem;
  898. if (item != null)
  899. {
  900. if (item.IsNode)
  901. {
  902. if (!destType.Match(item, context))
  903. throw new XQueryException(Properties.Resources.XPTY0004,
  904. new XQuerySequenceType(item.XmlType, XmlTypeCardinality.OneOrMore, null), destType);
  905. return item;
  906. }
  907. else
  908. return XQueryConvert.ValueAs(item.TypedValue, destType,
  909. context.nameTable, context.NamespaceManager);
  910. }
  911. return XQueryConvert.ValueAs(value, destType, context.nameTable, context.NamespaceManager);
  912. }
  913. }
  914. else
  915. return new NodeIterator(XPathFactory.ValueIterator(XQueryNodeIterator.Create(value), destType, context));
  916. }
  917. public static object TreatAs([Implict] Executive engine, object value, XQuerySequenceType destType)
  918. {
  919. XQueryContext context = (XQueryContext)engine.Owner;
  920. if (destType == XQuerySequenceType.Item)
  921. return value;
  922. if (value == Undefined.Value)
  923. {
  924. if (destType.Cardinality == XmlTypeCardinality.ZeroOrMore)
  925. return EmptyIterator.Shared;
  926. if (destType.TypeCode != XmlTypeCode.None && destType.Cardinality != XmlTypeCardinality.ZeroOrOne)
  927. throw new XQueryException(Properties.Resources.XPTY0004, "empty-sequence()", destType);
  928. return Undefined.Value;
  929. }
  930. if (destType.Cardinality == XmlTypeCardinality.One ||
  931. destType.Cardinality == XmlTypeCardinality.ZeroOrOne)
  932. {
  933. object res;
  934. XQueryNodeIterator iter = value as XQueryNodeIterator;
  935. if (iter != null)
  936. {
  937. iter = iter.Clone();
  938. if (!iter.MoveNext())
  939. {
  940. if (destType.TypeCode != XmlTypeCode.None &&
  941. (destType.Cardinality == XmlTypeCardinality.One || destType.Cardinality == XmlTypeCardinality.OneOrMore))
  942. throw new XQueryException(Properties.Resources.XPTY0004, "empty-sequence()", destType);
  943. return Undefined.Value;
  944. }
  945. if (destType.TypeCode == XmlTypeCode.None)
  946. throw new XQueryException(Properties.Resources.XPTY0004,
  947. new XQuerySequenceType(iter.Current.XmlType, XmlTypeCardinality.OneOrMore, null), "empty-sequence()");
  948. if (destType.IsNode)
  949. {
  950. if (!destType.Match(iter.Current, context))
  951. throw new XQueryException(Properties.Resources.XPTY0004,
  952. new XQuerySequenceType(iter.Current.XmlType, XmlTypeCardinality.OneOrMore, null), destType);
  953. res = iter.Current.Clone();
  954. }
  955. else
  956. res = XQueryConvert.TreatValueAs(iter.Current.TypedValue, destType);
  957. if (iter.MoveNext())
  958. throw new XQueryException(Properties.Resources.MoreThanOneItem);
  959. return res;
  960. }
  961. else
  962. {
  963. XPathItem item = value as XPathItem;
  964. if (item != null)
  965. {
  966. if (item.IsNode)
  967. {
  968. if (!destType.Match(item, context))
  969. throw new XQueryException(Properties.Resources.XPTY0004,
  970. new XQuerySequenceType(item.XmlType, XmlTypeCardinality.OneOrMore, null), destType);
  971. return item;
  972. }
  973. else
  974. return XQueryConvert.TreatValueAs(item.TypedValue, destType);
  975. }
  976. return XQueryConvert.TreatValueAs(value, destType);
  977. }
  978. }
  979. else
  980. return new NodeIterator(XPathFactory.TreatIterator(
  981. XQueryNodeIterator.Create(value), destType, context));
  982. }
  983. public static object CastToItem([Implict] Executive executive,
  984. object value, XQuerySequenceType destType)
  985. {
  986. XQueryContext context = (XQueryContext)executive.Owner;
  987. if (value == null)
  988. value = CoreServices.Generation.RuntimeOps.False;
  989. else
  990. {
  991. value = Atomize(value);
  992. if (value == Undefined.Value)
  993. {
  994. if (destType.TypeCode == XmlTypeCode.String)
  995. return String.Empty;
  996. return value;
  997. }
  998. }
  999. XmlTypeCode typeCode = XQuerySequenceType.GetXmlTypeCode(value.GetType());
  1000. XmlSchemaType xmlType = XmlSchemaSimpleType.GetBuiltInSimpleType(typeCode);
  1001. return XQueryConvert.ChangeType(xmlType, value,
  1002. destType, context.nameTable, context.NamespaceManager);
  1003. }
  1004. public static bool InstanceOf([Implict] Executive engine, object value, XQuerySequenceType destType)
  1005. {
  1006. XQueryContext context = (XQueryContext)engine.Owner;
  1007. if (value == Undefined.Value)
  1008. return destType.Cardinality == XmlTypeCardinality.ZeroOrOne ||
  1009. destType.Cardinality == XmlTypeCardinality.ZeroOrMore;
  1010. if (value == null)
  1011. value = CoreServices.Generation.RuntimeOps.False;
  1012. XQueryNodeIterator iter = value as XQueryNodeIterator;
  1013. if (iter != null)
  1014. {
  1015. int num = 0;
  1016. foreach (XPathItem item in iter)
  1017. {
  1018. if (num == 1)
  1019. {
  1020. if (destType.Cardinality == XmlTypeCardinality.ZeroOrOne ||
  1021. destType.Cardinality == XmlTypeCardinality.One)
  1022. return false;
  1023. }
  1024. if (!destType.Match(item, context))
  1025. return false;
  1026. num++;
  1027. }
  1028. if (num == 0)
  1029. {
  1030. if (destType.TypeCode != XmlTypeCode.None && (destType.Cardinality == XmlTypeCardinality.One ||
  1031. destType.Cardinality == XmlTypeCardinality.OneOrMore))
  1032. return false;
  1033. }
  1034. return true;
  1035. }
  1036. else
  1037. {
  1038. if (destType.ItemType == value.GetType())
  1039. return true;
  1040. XPathItem item = value as XPathItem;
  1041. if (item == null)
  1042. item = new XQueryItem(value);
  1043. return destType.Match(item, context);
  1044. }
  1045. }
  1046. public static bool Castable([Implict] Executive engine, object value, XQuerySequenceType destType, Type exprType)
  1047. {
  1048. try
  1049. {
  1050. CastTo(engine, value, destType, exprType);
  1051. return true;
  1052. }
  1053. catch(XQueryException)
  1054. {
  1055. return false;
  1056. }
  1057. }
  1058. public static bool SameNode(object a, object b)
  1059. {
  1060. XPathNavigator nav1 = (XPathNavigator)a;
  1061. XPathNavigator nav2 = (XPathNavigator)b;
  1062. return nav1.ComparePosition(nav2) == XmlNodeOrder.Same;
  1063. }
  1064. public static bool PrecedingNode(object a, object b)
  1065. {
  1066. XPathNavigator nav1 = (XPathNavigator)a;
  1067. XPathNavigator nav2 = (XPathNavigator)b;
  1068. XPathComparer comp = new XPathComparer();
  1069. return comp.Compare(nav1, nav2) == -1;
  1070. }
  1071. public static bool FollowingNode(object a, object b)
  1072. {
  1073. XPathNavigator nav1 = (XPathNavigator)a;
  1074. XPathNavigator nav2 = (XPathNavigator)b;
  1075. XPathComparer comp = new XPathComparer();
  1076. return comp.Compare(nav1, nav2) == 1;
  1077. }
  1078. private static void MagnitudeRelationship(XQueryContext context, XPathItem item1, XPathItem item2,
  1079. out object x, out object y)
  1080. {
  1081. x = item1.TypedValue;
  1082. y = item2.TypedValue;
  1083. if (x is UntypedAtomic)
  1084. {
  1085. if (ValueProxy.IsNumeric(y.GetType()))
  1086. x = Convert.ToDouble(x, CultureInfo.InvariantCulture);
  1087. else
  1088. if (y is String)
  1089. x = x.ToString();
  1090. else if (!(y is UntypedAtomic))
  1091. x = item1.ChangeType(new XQuerySequenceType(item2.XmlType.TypeCode), context).TypedValue;
  1092. }
  1093. if (y is UntypedAtomic)
  1094. {
  1095. if (ValueProxy.IsNumeric(x.GetType()))
  1096. y = Convert.ToDouble(y, CultureInfo.InvariantCulture);
  1097. else
  1098. if (x is String)
  1099. y = y.ToString();
  1100. else if (!(x is UntypedAtomic))
  1101. y = item2.ChangeType(new XQuerySequenceType(item1.XmlType.TypeCode), context).TypedValue;
  1102. }
  1103. }
  1104. public static bool GeneralEQ([Implict] Executive executive, object a, object b)
  1105. {
  1106. XQueryContext context = (XQueryContext)executive.Owner;
  1107. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1108. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1109. while (iter1.MoveNext())
  1110. {
  1111. XQueryNodeIterator iter = iter2.Clone();
  1112. while (iter.MoveNext())
  1113. {
  1114. object x;
  1115. object y;
  1116. MagnitudeRelationship(context, iter1.Current, iter.Current, out x, out y);
  1117. if (executive.OperatorEq(x, y) != null)
  1118. return true;
  1119. }
  1120. }
  1121. return false;
  1122. }
  1123. public static bool GeneralGT([Implict] Executive executive, object a, object b)
  1124. {
  1125. XQueryContext context = (XQueryContext)executive.Owner;
  1126. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1127. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1128. while (iter1.MoveNext())
  1129. {
  1130. XQueryNodeIterator iter = iter2.Clone();
  1131. while (iter.MoveNext())
  1132. {
  1133. object x;
  1134. object y;
  1135. MagnitudeRelationship(context, iter1.Current, iter.Current, out x, out y);
  1136. if (executive.OperatorGt(x, y) != null)
  1137. return true;
  1138. }
  1139. }
  1140. return false;
  1141. }
  1142. public static bool GeneralNE([Implict] Executive executive, object a, object b)
  1143. {
  1144. XQueryContext context = (XQueryContext)executive.Owner;
  1145. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1146. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1147. while (iter1.MoveNext())
  1148. {
  1149. XQueryNodeIterator iter = iter2.Clone();
  1150. while (iter.MoveNext())
  1151. {
  1152. object x;
  1153. object y;
  1154. MagnitudeRelationship(context, iter1.Current, iter.Current, out x, out y);
  1155. if (executive.OperatorEq(x, y) == null)
  1156. return true;
  1157. }
  1158. }
  1159. return false;
  1160. }
  1161. public static bool GeneralGE([Implict] Executive executive, object a, object b)
  1162. {
  1163. XQueryContext context = (XQueryContext)executive.Owner;
  1164. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1165. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1166. while (iter1.MoveNext())
  1167. {
  1168. XQueryNodeIterator iter = iter2.Clone();
  1169. while (iter.MoveNext())
  1170. {
  1171. object x;
  1172. object y;
  1173. MagnitudeRelationship(context, iter1.Current, iter.Current, out x, out y);
  1174. if (executive.OperatorEq(x, y) != null || executive.OperatorGt(x, y) != null)
  1175. return true;
  1176. }
  1177. }
  1178. return false;
  1179. }
  1180. public static bool GeneralLT([Implict] Executive executive, object a, object b)
  1181. {
  1182. XQueryContext context = (XQueryContext)executive.Owner;
  1183. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1184. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1185. while (iter1.MoveNext())
  1186. {
  1187. XQueryNodeIterator iter = iter2.Clone();
  1188. while (iter.MoveNext())
  1189. {
  1190. object x;
  1191. object y;
  1192. MagnitudeRelationship(context, iter1.Current, iter.Current, out x, out y);
  1193. if (executive.OperatorGt(y, x) != null)
  1194. return true;
  1195. }
  1196. }
  1197. return false;
  1198. }
  1199. public static bool GeneralLE([Implict] Executive executive, object a, object b)
  1200. {
  1201. XQueryContext context = (XQueryContext)executive.Owner;
  1202. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1203. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1204. while (iter1.MoveNext())
  1205. {
  1206. XQueryNodeIterator iter = iter2.Clone();
  1207. while (iter.MoveNext())
  1208. {
  1209. object x;
  1210. object y;
  1211. MagnitudeRelationship(context, iter1.Current, iter.Current, out x, out y);
  1212. if (executive.OperatorEq(x, y) != null || executive.OperatorGt(y, x) != null)
  1213. return true;
  1214. }
  1215. }
  1216. return false;
  1217. }
  1218. public static XQueryNodeIterator GetRange(object arg1, object arg2)
  1219. {
  1220. object lo = Atomize(arg1);
  1221. if (lo == Undefined.Value)
  1222. return EmptyIterator.Shared;
  1223. if (lo is UntypedAtomic)
  1224. {
  1225. int i;
  1226. if (!Int32.TryParse(lo.ToString(), out i))
  1227. throw new XQueryException(Properties.Resources.XPTY0004,
  1228. new XQuerySequenceType(lo.GetType(), XmlTypeCardinality.One), "xs:integer in first argument op:range");
  1229. lo = i;
  1230. }
  1231. object high = Atomize(arg2);
  1232. if (high == Undefined.Value)
  1233. return EmptyIterator.Shared;
  1234. if (high is UntypedAtomic)
  1235. {
  1236. int i;
  1237. if (!Int32.TryParse(high.ToString(), out i))
  1238. throw new XQueryException(Properties.Resources.XPTY0004,
  1239. new XQuerySequenceType(lo.GetType(), XmlTypeCardinality.One), "xs:integer in second argument op:range");
  1240. high = i;
  1241. }
  1242. if (!Integer.IsDerivedSubtype(lo))
  1243. throw new XQueryException(Properties.Resources.XPTY0004,
  1244. new XQuerySequenceType(lo.GetType(), XmlTypeCardinality.One), "xs:integer in first argument op:range");
  1245. if (!Integer.IsDerivedSubtype(high))
  1246. throw new XQueryException(Properties.Resources.XPTY0004,
  1247. new XQuerySequenceType(high.GetType(), XmlTypeCardinality.One), "xs:integer in second argument op:range");
  1248. return new RangeIterator(Convert.ToInt32(lo), Convert.ToInt32(high));
  1249. }
  1250. public static XQueryNodeIterator Union([Implict] Executive executive, bool isOrdered, object a, object b)
  1251. {
  1252. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1253. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1254. XQueryContext context = (XQueryContext)executive.Owner;
  1255. if (isOrdered)
  1256. return new NodeIterator(XPathFactory.UnionIterator1(iter1, iter2), true);
  1257. else
  1258. return new NodeIterator(XPathFactory.UnionIterator2(iter1, iter2));
  1259. }
  1260. public static XQueryNodeIterator Except([Implict] Executive executive, bool isOrdered, object a, object b)
  1261. {
  1262. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1263. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1264. XQueryContext context = (XQueryContext)executive.Owner;
  1265. if (isOrdered)
  1266. return new NodeIterator(XPathFactory.IntersectExceptIterator1(true, iter1, iter2), true);
  1267. else
  1268. return new NodeIterator(XPathFactory.IntersectExceptIterator2(true, iter1, iter2));
  1269. }
  1270. public static XQueryNodeIterator Intersect([Implict] Executive executive, bool isOrdered, object a, object b)
  1271. {
  1272. XQueryNodeIterator iter1 = XQueryNodeIterator.Create(a);
  1273. XQueryNodeIterator iter2 = XQueryNodeIterator.Create(b);
  1274. XQueryContext context = (XQueryContext)executive.Owner;
  1275. if (isOrdered)
  1276. return new NodeIterator(XPathFactory.IntersectExceptIterator1(false, iter1, iter2), true);
  1277. else
  1278. return new NodeIterator(XPathFactory.IntersectExceptIterator2(false, iter1, iter2));
  1279. }
  1280. [XQuerySignature("root", Return = XmlTypeCode.Node, Cardinality = XmlTypeCardinality.ZeroOrOne)]
  1281. public static object GetRoot(IContextProvider provider)
  1282. {
  1283. return GetRoot(NodeValue(ContextNode(provider)));
  1284. }
  1285. [XQuerySignature("root", Return = XmlTypeCode.Node, Cardinality = XmlTypeCardinality.ZeroOrOne)]
  1286. public static object GetRoot([XQueryParameter(XmlTypeCode.Node,
  1287. Cardinality = XmlTypeCardinality.ZeroOrOne)] object node)
  1288. {
  1289. if (node == Undefined.Value)
  1290. return node;
  1291. XPathNavigator nav = node as XPathNavigator;
  1292. if (nav == null)
  1293. throw new XQueryException(Properties.Resources.XPTY0004,
  1294. new XQuerySequenceType(node.GetType(), XmlTypeCardinality.ZeroOrOne), "node()? in fn:root()");
  1295. XPathNavigator curr = nav.Clone();
  1296. curr.MoveToRoot();
  1297. return curr;
  1298. }
  1299. public static bool True()
  1300. {
  1301. return true;
  1302. }
  1303. public static bool False()
  1304. {
  1305. return false;
  1306. }
  1307. public static bool Not([XQueryParameter(XmlTypeCode.Item, Cardinality = XmlTypeCardinality.ZeroOrMore)] object value)
  1308. {
  1309. return !BooleanValue(value);
  1310. }
  1311. public static double Number([Implict] Executive engine, IContextProvider provider)
  1312. {
  1313. return Number(engine, Core.Atomize(Core.ContextNode(provider)));
  1314. }
  1315. public static double Number([Implict] Executive engine,
  1316. [XQueryParameter(XmlTypeCode.AnyAtomicType, Cardinality=XmlTypeCardinality.ZeroOrOne)] object value)
  1317. {
  1318. if (value == Undefined.Value || !(value is IConvertible))
  1319. return Double.NaN;
  1320. XQueryContext context = (XQueryContext)engine.Owner;
  1321. try
  1322. {
  1323. return (double)Convert.ChangeType(value, TypeCode.Double, context.DefaultCulture);
  1324. }
  1325. catch (FormatException)
  1326. {
  1327. return Double.NaN;
  1328. }
  1329. catch (InvalidCastException)
  1330. {
  1331. return Double.NaN;
  1332. }
  1333. }
  1334. public static object CastToNumber1([Implict] Executive engine, object value)
  1335. {
  1336. XQueryContext context = (XQueryContext)engine.Owner;
  1337. try
  1338. {
  1339. if (value is UntypedAtomic)
  1340. return Convert.ToDouble(value, context.DefaultCulture);
  1341. }
  1342. catch (FormatException)
  1343. {
  1344. throw new XQueryException(Properties.Resources.FORG0001, value, "xs:double?");
  1345. }
  1346. catch (InvalidCastException)
  1347. {
  1348. throw new XQueryException(Properties.Resources.FORG0001, value, "xs:double?");
  1349. }
  1350. return value;
  1351. }
  1352. public static double CastToNumber2([Implict] Executive engine, object value)
  1353. {
  1354. XQueryContext context = (XQueryContext)engine.Owner;
  1355. try
  1356. {
  1357. if (!(value is UntypedAtomic))
  1358. throw new XQueryException(Properties.Resources.XPTY0004,
  1359. new XQuerySequenceType(value.GetType(), XmlTypeCardinality.One), "xs:untypedAtomic?");
  1360. return Convert.ToDouble(value, context.DefaultCulture);
  1361. }
  1362. catch (FormatException)
  1363. {
  1364. throw new XQueryException(Properties.Resources.FORG0001, value, "xs:double?");
  1365. }
  1366. catch (InvalidCastException)
  1367. {
  1368. throw new XQueryException(Properties.Resources.FORG0001, value, "xs:double?");
  1369. }
  1370. }
  1371. public static double CastToNumber3([Implict] Executive engine, object value)
  1372. {
  1373. XQueryContext context = (XQueryContext)engine.Owner;
  1374. try
  1375. {
  1376. return Convert.ToDouble(value, context.DefaultCulture);
  1377. }
  1378. catch (FormatException)
  1379. {
  1380. throw new XQueryException(Properties.Resources.FORG0001, value, "xs:double?");
  1381. }
  1382. catch (InvalidCastException)
  1383. {
  1384. throw new XQueryException(Properties.Resources.FORG0001, value, "xs:double?");
  1385. }
  1386. }
  1387. public static string StringValue([Implict] Executive executive, IContextProvider provider)
  1388. {
  1389. return StringValue(executive, ContextNode(provider));
  1390. }
  1391. public static string StringValue([Implict] Executive executive,
  1392. [XQueryParameter(XmlTypeCode.Item, Cardinality=XmlTypeCardinality.ZeroOrOne)] object value)
  1393. {
  1394. if (value == Undefined.Value)
  1395. return "";
  1396. XQueryContext context = (XQueryContext)executive.Owner;
  1397. XQueryNodeIterator iter = value as XQueryNodeIterator;
  1398. if (iter != null)
  1399. {
  1400. iter = iter.Clone();
  1401. if (!iter.MoveNext())
  1402. return "";
  1403. string res = iter.Current.Value;
  1404. if (iter.MoveNext())
  1405. throw new XQueryException(Properties.Resources.MoreThanOneItem);
  1406. return res;
  1407. }
  1408. XPathItem item = value as XPathItem;
  1409. if (item != null)
  1410. return item.Value;
  1411. return XQueryConvert.ToString(value);
  1412. }
  1413. public static XQueryNodeIterator Validate([Implict] Executive executive, object val, bool lax)
  1414. {
  1415. XQueryContext context = (XQueryContext)executive.Owner;
  1416. return new NodeIterator(XPathFactory.ValidateIterator(
  1417. XQueryNodeIterator.Create(val), context.schemaSet, lax));
  1418. }
  1419. }
  1420. }