PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Examine/LuceneEngine/ExamineXmlExtensions.cs

#
C# | 227 lines | 125 code | 21 blank | 81 comment | 25 complexity | 956d188c8eba576f0601ed300d3f2220 MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Xml;
  4. using System.Xml.Linq;
  5. using System.Xml.XPath;
  6. namespace Examine.LuceneEngine
  7. {
  8. /// <summary>
  9. /// Static methods to help query umbraco xml
  10. /// </summary>
  11. public static class ExamineXmlExtensions
  12. {
  13. /// <summary>
  14. /// Translates a dictionary object, node id, and node type into the property xml structure used by the examine indexer
  15. /// </summary>
  16. /// <param name="?"></param>
  17. /// <returns>
  18. /// returns an XElement with the default Examine XML structure
  19. /// </returns>
  20. /// <example>
  21. /// <code>
  22. /// <![CDATA[
  23. /// <root>
  24. /// <node id="1234" nodeTypeAlias="yourIndexType">
  25. /// <data alias="fieldName1">Some data</data>
  26. /// <data alias="fieldName2">Some other data</data>
  27. /// </node>
  28. /// <node id="345" nodeTypeAlias="anotherIndexType">
  29. /// <data alias="fieldName3">More data</data>
  30. /// </node>
  31. /// </root>
  32. /// ]]>
  33. /// </code>
  34. /// </example>
  35. public static XElement ToExamineXml(this Dictionary<string, string> data, int nodeId, string nodeType)
  36. {
  37. return new XElement("node",
  38. //creates the element attributes
  39. new XAttribute("id", nodeId),
  40. new XAttribute("nodeTypeAlias", nodeType),
  41. //creates the data nodes
  42. data.Select(x => new XElement("data",
  43. new XAttribute("alias", x.Key),
  44. new XCData(x.Value))).ToList());
  45. }
  46. /// <summary>
  47. /// Converts an <see cref="System.Xml.XmlNode"/> to a <see cref="System.Xml.Linq.XElement"/>
  48. /// </summary>
  49. /// <param name="node">Node to convert</param>
  50. /// <returns>Converted node</returns>
  51. public static XElement ToXElement(this XmlNode node)
  52. {
  53. using (var x = new XmlNodeReader(node))
  54. {
  55. x.MoveToContent();
  56. return XElement.Load(x);
  57. }
  58. }
  59. /// <summary>
  60. /// Creates an <see cref="System.Xml.Linq.XDocument"/> from the collection of <see cref="System.Xml.Linq.XElement"/>
  61. /// </summary>
  62. /// <param name="elements">Elements to create document from</param>
  63. /// <returns>Document containing elements</returns>
  64. public static XDocument ToXDocument(this IEnumerable<XElement> elements)
  65. {
  66. if (elements.Count() > 0)
  67. {
  68. return new XDocument(new XElement("nodes", elements));
  69. }
  70. return null;
  71. }
  72. /// <summary>
  73. /// Converts an umbraco library call to an XDocument
  74. /// </summary>
  75. /// <param name="xml"></param>
  76. /// <returns></returns>
  77. public static XDocument ToXDocument(this XPathNodeIterator xml)
  78. {
  79. if (xml.Count == 1)
  80. {
  81. //ensure its readable.
  82. if (xml.MoveNext())
  83. {
  84. //if ever the id is -1 then it's returned the whole tree which means its not found
  85. //TODO: This is bug with older umbraco versions, i'm fairly sure it's fixed in new ones
  86. //but just in case, we'll keep this here.
  87. if (xml.Current.InnerXml.StartsWith("<root"))
  88. return null;
  89. return XDocument.Load(xml.Current.ReadSubtree());
  90. }
  91. return null;
  92. }
  93. else if (xml.Count > 1)
  94. {
  95. //create an XDocument and add a node to it
  96. XDocument xDoc = new XDocument(new XElement("nodes"));
  97. var rootNode = xDoc.Elements().First();
  98. //Import all elements from umbraco to the root node
  99. while (xml.MoveNext())
  100. {
  101. rootNode.Add(XElement.Load(xml.Current.ReadSubtree()));
  102. }
  103. return xDoc;
  104. }
  105. return null;
  106. }
  107. /// <summary>
  108. /// Checks if the XElement is an umbraco property based on an alias.
  109. /// This works for both types of schemas
  110. /// </summary>
  111. /// <param name="x"></param>
  112. /// <param name="alias"></param>
  113. /// <returns></returns>
  114. public static bool IsExamineProperty(this XElement x, string alias)
  115. {
  116. if ((x.Name == alias) //this will match if its the new schema
  117. || (x.Name == "data" && (string)x.Attribute("nodeTypeAlias") == alias)) //this will match old schema
  118. {
  119. return true;
  120. }
  121. return false;
  122. }
  123. /// <summary>
  124. /// Returns true if the XElement is recognized as an umbraco xml NODE (doc type)
  125. /// </summary>
  126. /// <param name="x"></param>
  127. /// <returns></returns>
  128. public static bool IsExamineElement(this XElement x)
  129. {
  130. var id = (string) x.Attribute("id");
  131. if (string.IsNullOrEmpty(id))
  132. {
  133. return false;
  134. }
  135. int parsedId;
  136. if (int.TryParse(id, out parsedId))
  137. {
  138. if (parsedId > 0)
  139. {
  140. return true;
  141. }
  142. }
  143. return false;
  144. }
  145. /// <summary>
  146. /// This takes into account both schemas and returns the node type alias.
  147. /// If this isn't recognized as an element node, this returns an empty string
  148. /// </summary>
  149. /// <param name="x"></param>
  150. /// <returns></returns>
  151. public static string ExamineNodeTypeAlias(this XElement x)
  152. {
  153. return !x.IsExamineElement() ? string.Empty
  154. : string.IsNullOrEmpty(((string)x.Attribute("nodeTypeAlias"))) ? x.Name.LocalName
  155. : (string)x.Attribute("nodeTypeAlias");
  156. }
  157. /// <summary>
  158. /// Returns the property value for the doc type element (such as id, path, etc...)
  159. /// If the element is not an umbraco doc type node, or the property name isn't found, it returns String.Empty
  160. /// </summary>
  161. /// <param name="x"></param>
  162. /// <param name="alias"></param>
  163. /// <returns></returns>
  164. public static string SelectExaminePropertyValue(this XElement x, string alias)
  165. {
  166. if (alias == "nodeTypeAlias")
  167. {
  168. return x.ExamineNodeTypeAlias();
  169. }
  170. else
  171. {
  172. return (string)x.Attribute(alias);
  173. }
  174. }
  175. /// <summary>
  176. /// Returns umbraco value for a data element with the specified alias.
  177. /// </summary>
  178. /// <param name="xml"></param>
  179. /// <param name="alias"></param>
  180. /// <returns></returns>
  181. public static string SelectExamineDataValue(this XElement xml, string alias)
  182. {
  183. if (!xml.IsExamineElement())
  184. return string.Empty;
  185. XElement nodeData = null;
  186. //if there is data children with attributes, we're on the old
  187. if (xml.Elements("data").Where(x => x.HasAttributes).Count() > 0)
  188. {
  189. nodeData = xml.Elements("data").SingleOrDefault(x => ((string)x.Attribute("alias")).ToUpper() == alias.ToUpper());
  190. }
  191. else
  192. {
  193. //find the element with the uppercased name (umbraco camel cases things in xml even if the alias isn't)
  194. nodeData = xml.Elements().Where(x => x.Name.ToString().ToUpper() == alias.ToUpper()).FirstOrDefault();
  195. }
  196. if (nodeData == null)
  197. {
  198. return string.Empty;
  199. }
  200. else
  201. {
  202. return nodeData.Value;
  203. }
  204. }
  205. }
  206. }