169 lines
5.2 KiB
C#
169 lines
5.2 KiB
C#
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Xml.Linq;
|
|
using Examine;
|
|
|
|
namespace Umbraco.Cms.Tests.Integration.Umbraco.Examine.Lucene.UmbracoExamine;
|
|
|
|
/// <summary>
|
|
/// LEGACY!! Static methods to help query umbraco xml
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This should be deleted when we remove the old xml published content with tests which should be replaced with
|
|
/// nucache tests
|
|
/// </remarks>
|
|
internal static class ExamineExtensions
|
|
{
|
|
/// <summary>
|
|
/// Returns true if the XElement is recognized as an umbraco xml NODE (doc type)
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <returns></returns>
|
|
internal static bool IsExamineElement(this XElement x)
|
|
{
|
|
var id = (string)x.Attribute("id");
|
|
if (string.IsNullOrEmpty(id))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (int.TryParse(id, out int parsedId))
|
|
{
|
|
if (parsedId > 0)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This takes into account both schemas and returns the node type alias.
|
|
/// If this isn't recognized as an element node, this returns an empty string
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <returns></returns>
|
|
internal static string ExamineNodeTypeAlias(this XElement x) =>
|
|
string.IsNullOrEmpty((string)x.Attribute("nodeTypeAlias"))
|
|
? x.Name.LocalName
|
|
: (string)x.Attribute("nodeTypeAlias");
|
|
|
|
/// <summary>
|
|
/// Returns umbraco value for a data element with the specified alias.
|
|
/// </summary>
|
|
/// <param name="xml"></param>
|
|
/// <param name="alias"></param>
|
|
/// <returns></returns>
|
|
internal static string SelectExamineDataValue(this XElement xml, string alias)
|
|
{
|
|
XElement nodeData = null;
|
|
|
|
//if there is data children with attributes, we're on the old
|
|
if (xml.Elements("data").Any(x => x.HasAttributes))
|
|
{
|
|
nodeData = xml.Elements("data").SingleOrDefault(x =>
|
|
string.Equals((string)x.Attribute("alias"), alias, StringComparison.InvariantCultureIgnoreCase));
|
|
}
|
|
else
|
|
{
|
|
nodeData = xml.Elements().FirstOrDefault(x =>
|
|
string.Equals(x.Name.ToString(), alias, StringComparison.InvariantCultureIgnoreCase));
|
|
}
|
|
|
|
if (nodeData == null)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
if (!nodeData.HasElements)
|
|
{
|
|
return nodeData.Value;
|
|
}
|
|
|
|
//it has sub elements so serialize them
|
|
var reader = nodeData.CreateReader();
|
|
reader.MoveToContent();
|
|
return reader.ReadInnerXml();
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public static ValueSet ConvertToValueSet(this XElement xml, string indexCategory)
|
|
{
|
|
if (!xml.IsExamineElement())
|
|
{
|
|
throw new InvalidOperationException("Not a supported Examine XML structure");
|
|
}
|
|
|
|
var allVals = xml.SelectExamineAllValues();
|
|
var id = (string)xml.Attribute("id");
|
|
//we will use this as the item type, but we also need to add this as the 'nodeTypeAlias' as part of the properties
|
|
//since this is what Umbraco expects
|
|
var nodeTypeAlias = xml.ExamineNodeTypeAlias();
|
|
|
|
allVals["nodeTypeAlias"] = nodeTypeAlias;
|
|
var set = new ValueSet(id, indexCategory, nodeTypeAlias, allVals);
|
|
return set;
|
|
}
|
|
|
|
internal static Dictionary<string, object> SelectExamineAllValues(this XElement xml)
|
|
{
|
|
var attributeValues = xml.Attributes().ToDictionary(x => x.Name.LocalName, x => x.Value);
|
|
var dataValues = xml.SelectExamineDataValues();
|
|
foreach (var v in attributeValues)
|
|
//override the data values with attribute values if they do match, otherwise add
|
|
{
|
|
dataValues[v.Key] = v.Value;
|
|
}
|
|
|
|
return dataValues;
|
|
}
|
|
|
|
internal static Dictionary<string, object> SelectExamineDataValues(this XElement xml)
|
|
{
|
|
//resolve all element data at once since it is much faster to do this than to relookup all of the XML data
|
|
//using Linq and the node.Elements() methods re-gets all of them.
|
|
var elementValues = new Dictionary<string, object>();
|
|
foreach (var x in xml.Elements())
|
|
{
|
|
if (x.Attribute("id") != null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string key;
|
|
if (x.Name.LocalName == "data")
|
|
//it's the legacy schema
|
|
{
|
|
key = (string)x.Attribute("alias");
|
|
}
|
|
else
|
|
{
|
|
key = x.Name.LocalName;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(key))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!x.HasElements)
|
|
{
|
|
elementValues[key] = x.Value;
|
|
}
|
|
else
|
|
//it has sub elements so serialize them
|
|
{
|
|
using (var reader = x.CreateReader())
|
|
{
|
|
reader.MoveToContent();
|
|
elementValues[key] = reader.ReadInnerXml();
|
|
}
|
|
}
|
|
}
|
|
|
|
return elementValues;
|
|
}
|
|
}
|