示例#1
0
        private void FillIn(Expression xpath, XmlNode topContext)
        {
            //initialize the context node
            XmlNode current = topContext;

            //start looking down the document tree
            for (int length = 1; length <= xpath.StepCount; ++length)
            {
                Expression sub = xpath.SubExpression(length);

                //check to see if the node already exists...
                XmlNodeList nodes = topContext.SelectNodes(sub.ToString(true), this._namespaces);

                if (nodes.Count == 0)
                {
                    //... and create it if it doesn't
                    LocationStep step = sub.LastStep;
                    if (step.IsAttribute)
                    {
                        XmlAttribute attribute = this._document.CreateAttribute(step.NodeTest.Test);
                        current.Attributes.Append(attribute);
                        current = attribute;
                    }
                    else
                    {
                        string  namespaceUri = this._namespaces.LookupNamespace(step.NodeTest.Namespace);
                        XmlNode element      = this._document.CreateElement(step.NodeTest.Namespace, step.NodeTest.Test, namespaceUri);
                        current.AppendChild(element);
                        current = element;
                    }

                    //if there were attribute filters applied to the xpath, then apply them here
                    if (step.Predicates.Count > 0)
                    {
                        foreach (Predicate predicate in step.Predicates)
                        {
                            if (predicate.IsAttributeFilter)
                            {
                                XmlAttribute attribute = this._document.CreateAttribute(predicate.FilterKey.Substring(1));
                                attribute.Value = predicate.FilterValue;
                                current.Attributes.Append(attribute);
                            }
                        }
                    }
                }
                else if (nodes.Count == 1) //...otherwise, advance the context
                {
                    current = nodes[0];
                }
                else //in the case of multiples, do it to all of them
                {
                    foreach (XmlNode child in nodes)
                    {
                        FillIn(xpath.SubExpression(length, xpath.StepCount - length), child);
                    }
                }
            }
        }
示例#2
0
 /// <summary>
 /// Adds a location step to the end of the xpath, if the current xpath does not reference an Attribute
 /// </summary>
 /// <param name="locationStep"></param>
 public void AddStep(LocationStep locationStep)
 {
     if (!this.IsAttribute)
     {
         this._components.Add(locationStep);
     }
     if (this._standardPrefix != null)
     {
         locationStep.NodeTest.Namespace = this._standardPrefix;
     }
 }
示例#3
0
 /// <summary>
 /// Compares two location steps for equality. They must represent the same Axis Specifier, same Node Test
 /// and equivalent sets of Predicates.
 /// </summary>
 /// <param name="obj"></param>
 /// <returns></returns>
 public override bool Equals(object obj)
 {
     if (obj is LocationStep)
     {
         LocationStep step = (LocationStep)obj;
         return(this.ToString(true).Equals(step.ToString(true)));
     }
     else
     {
         return(false);
     }
 }
示例#4
0
        public LocationStep GetLocationStepByNodeTest(string p)
        {
            LocationStep locationStep = null;

            foreach (LocationStep step in this._components)
            {
                if (step.NodeTest.Test.Equals(p))
                {
                    locationStep = step;
                }
            }
            return(locationStep);
        }
示例#5
0
 /// <summary>
 /// Tokenizes a provided XPath expression
 /// </summary>
 /// <param name="exp"></param>
 public Expression(string exp)
     : this()
 {
     try
     {
         exp = exp.Replace("//", "/descendant::");
         if (exp[0] == '/')
         {
             this._isFromRoot = true;
             exp = exp.Substring(1);
         }
         else
         {
             this._isFromRoot = false;
         }
         string[] parts           = exp.Split('/');
         string   namespacePrefix = null;
         bool     allHavePrefix   = true;
         foreach (string part in parts)
         {
             LocationStep step = new LocationStep(part);
             this._components.Add(step);
             if (step.NodeTest.Namespace == null || (namespacePrefix != null && !step.NodeTest.Namespace.Equals(namespacePrefix)))
             {
                 allHavePrefix = false;
             }
             else
             {
                 namespacePrefix = step.NodeTest.Namespace;
             }
         }
         if (allHavePrefix)
         {
             this._standardPrefix = namespacePrefix;
         }
     }
     catch (Exception exception)
     {
         throw new Exception(string.Format("Could not construct XPath expression from input string(\"{0}\")", exp), exception);
     }
 }