public AdkXPathStep( AdkAxisType axis, AdkNodeTest nodeTest, params AdkExpression[] predicates ) { fAxis = axis; fNodeTest = nodeTest; fPredicates = predicates; }
/// <summary> /// Manually builds out a path to support the necessary mapping needs of the /// ADK. By default, the JXPath implementation does not allow /// context-dependend predicates (e.g. PhoneNumber[@Type='0096'] to be used /// in XPaths that create the path. This implementation manually steps /// through the XPath and builds it out. It's primary intent is to provide /// the behavior that was present in the ADK before JXPath was used for /// mapping /// </summary> /// <param name="expr">The Path expression to build out</param> /// <param name="context"></param> /// <returns></returns> private INodePointer BuildADKPathWithPredicates(String expr, XsltContext context) { // Use the set of expression steps to determine which parts of the // path already exist. Note that the order of evaluation used is optimized // for first-time creation of elements. In other words, the path chosen was // to evalaute the expression steps from the beginning rather than the end // because for outbound mappings, that order will generally be the most efficient AdkXPathStep[] steps = XPathParser.Parse(expr); int currentStep = 0; StringBuilder pathSoFar = new StringBuilder(); INodePointer parent = fContextPointer; INodePointer current = null; for ( ; currentStep < steps.Length; currentStep++) { current = FindChild(fDefaultNavigator, pathSoFar, steps[currentStep]); if (current == null) { break; } pathSoFar.Append("/"); pathSoFar.Append(steps[currentStep].ToString()); parent = current; } if (current != null) { // We traversed the entire path and came up with a result. // That means that the element we are trying to build the // path to already exists. We will not create this path, so // return null; return(null); } // We've traversed down to the level where we think we need to // add a child. However, there are cases where this is not the proper // location. For example, in SIF 1.5r1, the StudentAddressList element is // repeatable and Address is not. It would not be proper to add a new Address // element under StudentAddressList. Instead, the algorithm needs to back // up the stack until it reaches the next repeatable element for the current // version of SIF // The following code is primarily in place for the StudentAddressList case, which is // why the isContextDependent() logic applies. Currently, there is no known other place // where this checking needs to occur. if (currentStep > 0 && steps[currentStep].IsContextDependent()) { int step = currentStep; INodePointer stepParent = parent; while (step > -1) // don't evaluate step 0 at the root of the object because this problem doesn't apply there { if (parent is SifElementPointer) { SifElementPointer sifParentPointer = (SifElementPointer)stepParent; AdkNodeTest nt = steps[step].NodeTest; if (nt is AdkNodeNameTest) { SifElementPointer.AddChildDirective result = sifParentPointer.GetAddChildDirective(((AdkNodeNameTest)nt).NodeName); if (result != SifElementPointer.AddChildDirective.DONT_ADD_NOT_REPEATABLE) { break; } } } else { break; } step--; stepParent = stepParent.Parent; } if (step > -1 && step != currentStep) { currentStep = step; parent = stepParent; } } // At this point, we have a parent element and the index of the current // step to evaluate //InitialContext context = new InitialContext( new RootContext( this, (NodePointer) getContextPointer())); for ( ; currentStep < steps.Length; currentStep++) { AdkNodeTest nt = steps[currentStep].NodeTest; if (nt is AdkNodeNameTest) { current = parent.CreateChild(this, ((AdkNodeNameTest)nt).NodeName, 0); if (current == null) { throw new ArgumentException("Cannot evaluate expression step: " + steps[currentStep]); } foreach (AdkExpression predicate in steps[currentStep].Predicates) { CreatePredicateValues(current, predicate, context); } } else { throw new ArgumentException("Cannot evaluate expression step: " + steps[currentStep]); } parent = current; } // At the end, the 'parent' variable will contain the last element created by this function return(parent); }
public AdkXPathStep(AdkAxisType axis, AdkNodeTest nodeTest, params AdkExpression[] predicates) { fAxis = axis; fNodeTest = nodeTest; fPredicates = predicates; }