/// <summary> /// <para> /// Returns expresion where <paramref name="nodeContents" /> are converted to their relative /// XPath expressions and joined with "," operator. /// </para> /// The XPath expressions are modified so that the part belonging to represented class /// is replaced with the part belonging to structural representative /// </summary> /// <example> /// sequence {Item/prod-red/ProductSet Item/prod-red/Category} /// is returned as "Item/prod-blue/ProductSet, Item/prod-blue/Category" /// where prod-blue is a structural representative of prod-red. /// </example> public static XPathExpr ElementsListWithSRSubstitution(XsltGeneratorContext context, IEnumerable <NodeElementWrapper> nodeContents, IFromStructuralRepresentative structuralRepresentativeReplacement, string concatOperator) { List <XPathExpr> modified = new List <XPathExpr>(); foreach (PSMElement element in nodeContents.Inline().Where(c => c.ModelsElement())) { XPathExpr expr; if (structuralRepresentativeReplacement != null) { expr = GroupAwareProjectXPathWithSRSubstitution(context, element, structuralRepresentativeReplacement); } else { expr = GroupAwareProjectXPath(context, element, context.ChangeSet.OldVersion); } modified.Add(expr); } return(new XPathExpr(modified.ConcatWithSeparator(concatOperator))); }
/// <summary> /// Performs <see cref="GroupAwareProjectXPath"/> and substitutes steps in the result path according /// to structural representative information. (So the path is relative to the structural representative) /// </summary> /// <param name="context">The generator context.</param> /// <param name="element">The element.</param> /// <param name="structuralRepresentativeReplacement">The structural representative replacement.</param> /// <returns></returns> public static XPathExpr GroupAwareProjectXPathWithSRSubstitution(XsltGeneratorContext context, PSMElement element, IFromStructuralRepresentative structuralRepresentativeReplacement) { XPathExpr expr; if (structuralRepresentativeReplacement != null) { var cp = context.ProcessedPath; //if (PSMTreeIterator.AreInTheSamePSMTree(structuralRepresentativeReplacement.RepresentedPSMClass, structuralRepresentativeReplacement.StructuralRepresentative)) PSMElement representedOldAnc = PSMTreeIterator.GetSignificantAncestorOrSelf((PSMClass)structuralRepresentativeReplacement.RepresentedPSMClass.GetInVersion(context.ChangeSet.OldVersion)); PSMElement structuralRepresentativeOldAnc = PSMTreeIterator.GetSignificantAncestorOrSelf((PSMClass)structuralRepresentativeReplacement.StructuralRepresentative.GetInVersion(context.ChangeSet.OldVersion)); if (representedOldAnc != null) { context.ProcessedPath = GetXPathForNode(representedOldAnc, context.ChangeSet.OldVersion); } else { context.ProcessedPath = new XPathExpr("<virt-root>"); if (context.InGroup) { context.ProcessedPath = context.ProcessedPath.Append("/$cg"); } } string from = representedOldAnc != null?XsltTemplateNameManager.GetElementNameForSignificantElement(representedOldAnc) : null; string to = structuralRepresentativeOldAnc != null?XsltTemplateNameManager.GetElementNameForSignificantElement(structuralRepresentativeOldAnc) : null; XPathExpr e = null; if (from != null && to != null && !(context.ProcessedPath.ToString().EndsWith(from) && cp.ToString().EndsWith(to))) { e = ProjectXPath(cp, context.ProcessedPath, false); if (!XPathExpr.IsNullOrEmpty(e) && !String.IsNullOrEmpty(to) && !String.IsNullOrEmpty(from)) { if (e.ToString().Contains(from)) { e = new XPathExpr(e.ToString().Replace(from, to)); } } } expr = GroupAwareProjectXPath(context, element, context.ChangeSet.OldVersion); if (!XPathExpr.IsNullOrEmpty(e)) { // ReSharper disable PossibleNullReferenceException expr = e.Append("/" + expr); } // ReSharper restore PossibleNullReferenceException context.ProcessedPath = cp; } else { expr = GroupAwareProjectXPath(context, element, context.ChangeSet.OldVersion); } return(expr); }
/// <summary> /// <para> /// Returns expresion where <paramref name="attributes" /> are converted to their relative /// XPath expressions and joined with "," operator. /// </para> /// The XPath expressions are modified so that the part belonging to represented class /// is replaced with the part belonging to structural representative /// </summary> /// <example> /// sequence {Item/prod-red/@ProductSet Item/prod-red/@Category} /// is returned as "Item/prod-blue/@ProductSet, Item/prod-blue/@Category" /// where prod-blue is a structural representative of prod-red. /// </example> public static XPathExpr AttributeListWithSRSubstitution(XsltGeneratorContext context, IEnumerable <NodeAttributeWrapper> attributes, IFromStructuralRepresentative structuralRepresentativeReplacement, bool onlyExisting, string concatOperator) { List <XPathExpr> modified = new List <XPathExpr>(); foreach (PSMAttribute attribute in attributes.Inline()) { if (onlyExisting && !attribute.ExistsInVersion(context.ChangeSet.OldVersion)) { continue; } XPathExpr expr; if (structuralRepresentativeReplacement != null) { expr = GroupAwareProjectXPathWithSRSubstitution(context, attribute, structuralRepresentativeReplacement); } else { expr = GroupAwareProjectXPath(context, attribute, context.ChangeSet.OldVersion); } modified.Add(expr); } return(new XPathExpr(modified.ConcatWithSeparator(concatOperator))); }