public void CompileXPath(string xPath, bool isField, XmlNamespaceManager nsmgr) { if ((xPath == null) || (xPath.Length == 0)) { throw new XmlSchemaException("Sch_EmptyXPath", string.Empty); } string[] strArray = xPath.Split(new char[] { '|' }); ArrayList list = new ArrayList(strArray.Length); this.fAxisArray = new ArrayList(strArray.Length); try { for (int j = 0; j < strArray.Length; j++) { Axis axis = (Axis)XPathParser.ParseXPathExpresion(strArray[j]); list.Add(axis); } } catch { throw new XmlSchemaException("Sch_ICXpathError", xPath); } for (int i = 0; i < list.Count; i++) { Axis ast = (Axis)list[i]; Axis input = ast; if (input == null) { throw new XmlSchemaException("Sch_ICXpathError", xPath); } Axis axis4 = input; if (!IsAttribute(input)) { goto Label_013D; } if (!isField) { throw new XmlSchemaException("Sch_SelectorAttr", xPath); } this.SetURN(input, nsmgr); try { input = (Axis)input.Input; goto Label_013D; } catch { throw new XmlSchemaException("Sch_ICXpathError", xPath); } Label_00EB: if (IsSelf(input) && (ast != input)) { axis4.Input = input.Input; } else { axis4 = input; if (IsNameTest(input)) { this.SetURN(input, nsmgr); } } try { input = (Axis)input.Input; } catch { throw new XmlSchemaException("Sch_ICXpathError", xPath); } Label_013D: if ((input != null) && (IsNameTest(input) || IsSelf(input))) { goto Label_00EB; } axis4.Input = null; if (input == null) { if (IsSelf(ast) && (ast.Input != null)) { this.fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree((Axis)ast.Input), false)); } else { this.fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree(ast), false)); } } else { if (!IsDescendantOrSelf(input)) { throw new XmlSchemaException("Sch_ICXpathError", xPath); } try { input = (Axis)input.Input; } catch { throw new XmlSchemaException("Sch_ICXpathError", xPath); } if (((input == null) || !IsSelf(input)) || (input.Input != null)) { throw new XmlSchemaException("Sch_ICXpathError", xPath); } if (IsSelf(ast) && (ast.Input != null)) { this.fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree((Axis)ast.Input), true)); } else { this.fAxisArray.Add(new ForwardAxis(DoubleLinkAxis.ConvertTree(ast), true)); } } } }
/// <include file='doc\XPathReader.uex' path='docs/doc[@for="XPathReader.XPathReader"]/*' /> public XPathReader(XmlReader reader, String xpathexpr) { _Reader = reader; _IfQuery = QueryBuildRecord.ProcessNode(XPathParser.ParseXPathExpresion(xpathexpr)); // this will throw if xpathexpr is invalid }
// 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(ResXml.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.ParseXPathExpresion(xpath[i])); AstArray.Add(ast); } } catch { throw new XmlSchemaException(ResXml.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(ResXml.Sch_ICXpathError, xPath); } Axis top = stepAst; // attribute will have namespace too // field can have top attribute if (IsAttribute(stepAst)) { if (!isField) { throw new XmlSchemaException(ResXml.Sch_SelectorAttr, xPath); } else { SetURN(stepAst, nsmgr); try { stepAst = (Axis)(stepAst.Input); } catch { throw new XmlSchemaException(ResXml.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(ResXml.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(ResXml.Sch_ICXpathError, xPath); } try { stepAst = (Axis)(stepAst.Input); } catch { throw new XmlSchemaException(ResXml.Sch_ICXpathError, xPath); } if ((stepAst == null) || (!IsSelf(stepAst)) || (stepAst.Input != null)) { throw new XmlSchemaException(ResXml.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)); } } }