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);
        }
Beispiel #3
0
 public AdkXPathStep(AdkAxisType axis, AdkNodeTest nodeTest, params AdkExpression[] predicates)
 {
     fAxis       = axis;
     fNodeTest   = nodeTest;
     fPredicates = predicates;
 }