// 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)); } } }