public void CompileXPath (string xPath, bool isField, XmlNamespaceManager nsmgr) {
if ((xPath == null) || (xPath.Length == 0)) {
throw new XmlSchemaException(Res.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);
this.fAxisArray = new ArrayList(xpath.Length);
// throw compile exceptions
// can i only new one builder here then run compile several times??
try {
foreach (string value in xpath) {
// default ! isdesorself (no .//)
Axis ast = (Axis) (XPathParser.ParseXPathExpresion(value));
AstArray.Add (ast);
}
}
catch {
throw new XmlSchemaException(Res.Sch_ICXpathError, xPath);
}
Axis stepAst;
foreach (Axis ast in AstArray) {
// Restricted form
// field can have an attribute:
// throw exceptions during casting
if ((stepAst = ast) == null) {
throw new XmlSchemaException(Res.Sch_ICXpathError, xPath);
}
Axis top = stepAst;
// attribute will have namespace too
// field can have top attribute
if (IsAttribute (stepAst)) {
if (! isField) {
throw new XmlSchemaException(Res.Sch_SelectorAttr, xPath);
}
else {
SetURN (stepAst, nsmgr);
try {
stepAst = (Axis) (stepAst.Input);
}
catch {
throw new XmlSchemaException(Res.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(Res.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)) {
this.fAxisArray.Add ( new ForwardAxis ( DoubleLinkAxis.ConvertTree ((Axis) (ast.Input)), false));
}
else {
this.fAxisArray.Add ( new ForwardAxis ( DoubleLinkAxis.ConvertTree (ast), false));
}
continue;
}
if (! IsDescendantOrSelf (stepAst)) {
throw new XmlSchemaException(Res.Sch_ICXpathError, xPath);
}
try {
stepAst = (Axis) (stepAst.Input);
}
catch {
throw new XmlSchemaException(Res.Sch_ICXpathError, xPath);
}
if ((stepAst == null) || (! IsSelf (stepAst)) || (stepAst.Input != null)) {
throw new XmlSchemaException(Res.Sch_ICXpathError, xPath);
}
// trim top "." if it's not the only node
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));
}
}
}