예제 #1
0
        // don't return true or false, if it's invalid path, just throw exception during the process
        // for whitespace thing, i will directly trim the tree built here...
        public void CompileXPath(string xPath, bool isField, XmlNamespaceManager nsmgr)
        {
            if ((xPath == null) || (xPath.Length == 0))
            {
                throw new XmlSchemaException(SR.Sch_EmptyXPath, string.Empty);
            }

            // firstly i still need to have an ArrayList to store tree only...
            // can't new ForwardAxis right away
            string[]  xpath    = xPath.Split('|');
            ArrayList AstArray = new ArrayList(xpath.Length);

            _fAxisArray = new ArrayList(xpath.Length);

            // throw compile exceptions
            // can i only new one builder here then run compile several times??
            try
            {
                for (int i = 0; i < xpath.Length; ++i)
                {
                    // default ! isdesorself (no .//)
                    Axis ast = (Axis)(XPathParser.ParseXPathExpression(xpath[i]));
                    AstArray.Add(ast);
                }
            }
            catch
            {
                throw new XmlSchemaException(SR.Sch_ICXpathError, xPath);
            }

            Axis?stepAst;

            for (int i = 0; i < AstArray.Count; ++i)
            {
                Axis ast = (Axis)AstArray[i] !;
                // Restricted form
                // field can have an attribute:

                // throw exceptions during casting
                if ((stepAst = ast) == null)
                {
                    throw new XmlSchemaException(SR.Sch_ICXpathError, xPath);
                }

                Axis top = stepAst;

                // attribute will have namespace too
                // field can have top attribute
                if (IsAttribute(stepAst))
                {
                    if (!isField)
                    {
                        throw new XmlSchemaException(SR.Sch_SelectorAttr, xPath);
                    }
                    else
                    {
                        SetURN(stepAst, nsmgr);
                        try
                        {
                            stepAst = (Axis?)(stepAst.Input);
                        }
                        catch
                        {
                            throw new XmlSchemaException(SR.Sch_ICXpathError, xPath);
                        }
                    }
                }

                // field or selector
                while ((stepAst != null) && (IsNameTest(stepAst) || IsSelf(stepAst)))
                {
                    // trim tree "." node, if it's not the top one
                    if (IsSelf(stepAst) && (ast != stepAst))
                    {
                        top.Input = stepAst.Input;
                    }
                    else
                    {
                        top = stepAst;
                        // set the URN
                        if (IsNameTest(stepAst))
                        {
                            SetURN(stepAst, nsmgr);
                        }
                    }
                    try
                    {
                        stepAst = (Axis?)(stepAst.Input);
                    }
                    catch
                    {
                        throw new XmlSchemaException(SR.Sch_ICXpathError, xPath);
                    }
                }

                // the rest part can only be .// or null
                // trim the rest part, but need compile the rest part first
                top.Input = null;
                if (stepAst == null)
                {      // top "." and has other element beneath, trim this "." node too
                    if (IsSelf(ast) && (ast.Input != null))
                    {
                        _fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree((Axis)(ast.Input)), false));
                    }
                    else
                    {
                        _fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree(ast), false));
                    }
                    continue;
                }
                if (!IsDescendantOrSelf(stepAst))
                {
                    throw new XmlSchemaException(SR.Sch_ICXpathError, xPath);
                }
                try
                {
                    stepAst = (Axis?)(stepAst.Input);
                }
                catch
                {
                    throw new XmlSchemaException(SR.Sch_ICXpathError, xPath);
                }
                if ((stepAst == null) || (!IsSelf(stepAst)) || (stepAst.Input != null))
                {
                    throw new XmlSchemaException(SR.Sch_ICXpathError, xPath);
                }

                // trim top "." if it's not the only node
                if (IsSelf(ast) && (ast.Input != null))
                {
                    _fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree((Axis)(ast.Input)), true));
                }
                else
                {
                    _fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree(ast), true));
                }
            }
        }