/// <summary> /// Collapses all the elements under this element into a list. This includes all children of this element /// and all their children. Only elements of the specified type are returned. /// </summary> /// <typeparam name="TElement">The type of elements to get.</typeparam> /// <param name="scope">The scope that defines what elements to look at as part of the collapse.</param> /// <returns>A list of elements under the element.</returns> public List <TElement> CollapseChildren <TElement>(CollapseScope scope) where TElement : class { List <TElement> result; List <XliffElement> temp; temp = new List <XliffElement>(); this.CollapseChildren(scope, 0, new[] { typeof(TElement) }, null, temp); result = new List <TElement>(); foreach (XliffElement element in temp) { result.Add(element as TElement); } return(result); }
/// <summary> /// Collapses all the elements under this element into a list. This includes all children of this element /// and all their children. Only elements of the specified type are returned. /// </summary> /// <param name="scope">The scope that defines what elements to look at as part of the collapse.</param> /// <param name="depth">The depth of the recursion.</param> /// <param name="elementTypes">The types of children to return.</param> /// <param name="filterMethod">An optional method that will be called before children are added to the return /// list. If the method returns true for a specified child, the child may be returned along and its matching /// descendants. If the method returns false for a specified child, the child will not be returned, nor will /// any of its descendants.</param> /// <param name="list">The list of elements that match the type specified.</param> private void CollapseChildren( CollapseScope scope, int depth, Type[] elementTypes, Func <XliffElement, bool> filterMethod, List <XliffElement> list) { bool hasTypeMatch; bool processDescendants; if ((filterMethod == null) || filterMethod(this)) { processDescendants = ((depth == 0) && scope.HasFlag(CollapseScope.TopLevelDescendants)) || scope.HasFlag(CollapseScope.AllDescendants); hasTypeMatch = false; foreach (Type type in elementTypes) { if (type.IsInstanceOfType(this)) { hasTypeMatch = true; break; } } if (scope.HasFlag(CollapseScope.CurrentElement) && hasTypeMatch) { list.Add(this); } if (processDescendants) { int recurseDepth; recurseDepth = depth + 1; if (scope.HasFlag(CollapseScope.CoreElements) || scope.HasFlag(CollapseScope.Extensions)) { CollapseScope recurseScope; if (scope.HasFlag(CollapseScope.CoreElements)) { // The recursive call adds the element so CurrentElement must be included. recurseScope = scope | CollapseScope.CurrentElement; } else { // The recursive call adds the element so CurrentElement must not be included because only // extensions are expected. recurseScope = scope & ~CollapseScope.CurrentElement; } if (this.HasChildren) { foreach (ElementInfo child in this.GetChildren()) { child.Element.CollapseChildren( recurseScope, recurseDepth, elementTypes, filterMethod, list); } } } // Add extensions. if (scope.HasFlag(CollapseScope.Extensions) && (this is IExtensible)) { IExtensible extensible; CollapseScope recurseScope; extensible = (IExtensible)this; // The recursive call adds the element so CurrentElement must be included. Extensions may have // native Xliff types but those are treated as extensions in this context, so include // CoreElements in the recursive call. recurseScope = scope | CollapseScope.CurrentElement | CollapseScope.CoreElements; foreach (IExtension extension in extensible.Extensions) { foreach (ElementInfo info in extension.GetChildren()) { info.Element.CollapseChildren( recurseScope, recurseDepth, elementTypes, filterMethod, list); } } } } } }
/// <summary> /// Collapses all the elements for all the specified elements and returns them in a single list. The scope /// determines which elements to search in. Only elements of the specified type are returned. /// </summary> /// <typeparam name="TElement">The type of elements to get.</typeparam> /// <param name="elements">The elements to search in.</param> /// <param name="scope">The scope that defines what elements to look at as part of the collapse.</param> /// <returns>A list of elements under the element.</returns> internal static List <TElement> CollapseChildren <TElement>(IEnumerable <XliffElement> elements, CollapseScope scope) where TElement : class { List <TElement> result; result = new List <TElement>(); foreach (XliffElement element in elements) { result.AddRange(element.CollapseChildren <TElement>(scope)); } return(result); }