/** * translate an xpath path reference into a TreeReference * TreeReferences only support a subset of true xpath paths; restrictions are: * simple child name tests 'child::name', '.', and '..' allowed only * no predicates * all '..' steps must come before anything else */ public TreeReference getReference(Boolean allowPredicates) { TreeReference ref_ = new TreeReference(); Boolean parentsAllowed; switch (init_context) { case XPathPathExpr.INIT_CONTEXT_ROOT: ref_.setRefLevel(TreeReference.REF_ABSOLUTE); parentsAllowed = false; break; case XPathPathExpr.INIT_CONTEXT_RELATIVE: ref_.setRefLevel(0); parentsAllowed = true; break; default: throw new XPathUnsupportedException("filter expression"); } for (int i = 0; i < steps.Length; i++) { XPathStep step = steps[i]; if (!allowPredicates && step.predicates.Length > 0) { throw new XPathUnsupportedException("predicates"); } if (step.axis == XPathStep.AXIS_SELF) { if (step.test != XPathStep.TEST_TYPE_NODE) { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } } else if (step.axis == XPathStep.AXIS_PARENT) { if (!parentsAllowed || step.test != XPathStep.TEST_TYPE_NODE) { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } else { ref_.incrementRefLevel(); } } else if (step.axis == XPathStep.AXIS_ATTRIBUTE) { if (step.test == XPathStep.TEST_NAME) { ref_.add(step.name.ToString(), TreeReference.INDEX_ATTRIBUTE); parentsAllowed = false; //TODO: Can you step back from an attribute, or should this always be //the last step? } else { throw new XPathUnsupportedException("attribute step other than 'attribute::name"); } } else if (step.axis == XPathStep.AXIS_CHILD) { if (step.test == XPathStep.TEST_NAME) { ref_.add(step.name.ToString(), TreeReference.INDEX_UNBOUND); parentsAllowed = false; } else if (step.test == XPathStep.TEST_NAME_WILDCARD) { ref_.add(TreeReference.NAME_WILDCARD, TreeReference.INDEX_UNBOUND); parentsAllowed = false; } else { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } } else { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } } return(ref_); }
/// <summary> translate an xpath path reference into a TreeReference /// TreeReferences only support a subset of true xpath paths; restrictions are: /// simple child name tests 'child::name', '.', and '..' allowed only /// no predicates /// all '..' steps must come before anything else /// </summary> public virtual TreeReference getReference(bool allowPredicates) { TreeReference ref_Renamed = new TreeReference(); bool parentsAllowed; switch (init_context) { case XPathPathExpr.INIT_CONTEXT_ROOT: ref_Renamed.RefLevel = TreeReference.REF_ABSOLUTE; parentsAllowed = false; break; case XPathPathExpr.INIT_CONTEXT_RELATIVE: ref_Renamed.RefLevel = 0; parentsAllowed = true; break; case XPathPathExpr.INIT_CONTEXT_EXPR: if (this.filtExpr.x != null && this.filtExpr.x is XPathFuncExpr) { XPathFuncExpr func = (XPathFuncExpr)(this.filtExpr.x); if (func.id.ToString().Equals("instance")) { ref_Renamed.RefLevel = TreeReference.REF_ABSOLUTE; //i assume when refering the non main instance you have to be absolute parentsAllowed = false; if (func.args.Length != 1) { throw new XPathUnsupportedException("instance() function used with " + func.args.Length + " arguements. Expecting 1 arguement"); } if (!(func.args[0] is XPathStringLiteral)) { throw new XPathUnsupportedException("instance() function expecting 1 string literal arguement arguement"); } XPathStringLiteral strLit = (XPathStringLiteral)(func.args[0]); //we've got a non-standard instance in play, watch out if (strLit.s == null) { // absolute reference to the main instance ref_Renamed.Context = TreeReference.CONTEXT_ABSOLUTE; ref_Renamed.InstanceName = null; } else { ref_Renamed.Context = TreeReference.CONTEXT_INSTANCE; ref_Renamed.InstanceName = strLit.s; } } else { if (func.id.ToString().Equals("current")) { parentsAllowed = true; ref_Renamed.Context = TreeReference.CONTEXT_ORIGINAL; } else { //We only support expression root contexts for instance refs, everything else is an illegal filter throw new XPathUnsupportedException("filter expression"); } } } else { //We only support expression root contexts for instance refs, everything else is an illegal filter throw new XPathUnsupportedException("filter expression"); } break; default: throw new XPathUnsupportedException("filter expression"); } for (int i = 0; i < steps.Length; i++) { XPathStep step = steps[i]; if (step.axis == XPathStep.AXIS_SELF) { if (step.test != XPathStep.TEST_TYPE_NODE) { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } } else if (step.axis == XPathStep.AXIS_PARENT) { if (!parentsAllowed || step.test != XPathStep.TEST_TYPE_NODE) { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } else { ref_Renamed.incrementRefLevel(); } } else if (step.axis == XPathStep.AXIS_ATTRIBUTE) { if (step.test == XPathStep.TEST_NAME) { ref_Renamed.add(step.name.ToString(), TreeReference.INDEX_ATTRIBUTE); parentsAllowed = false; //TODO: Can you step back from an attribute, or should this always be //the last step? } else { throw new XPathUnsupportedException("attribute step other than 'attribute::name"); } } else if (step.axis == XPathStep.AXIS_CHILD) { if (step.test == XPathStep.TEST_NAME) { ref_Renamed.add(step.name.ToString(), TreeReference.INDEX_UNBOUND); parentsAllowed = true; } else if (step.test == XPathStep.TEST_NAME_WILDCARD) { ref_Renamed.add(TreeReference.NAME_WILDCARD, TreeReference.INDEX_UNBOUND); parentsAllowed = true; } else { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } } else { throw new XPathUnsupportedException("step other than 'child::name', '.', '..'"); } if (step.predicates.Length > 0) { int refLevel = ref_Renamed.RefLevel; List <XPathExpression> v = new List <XPathExpression>(); for (int j = 0; j < step.predicates.Length; j++) { v.addElement(step.predicates[j]); } ref_Renamed.addPredicate(i, v); } } return(ref_Renamed); }
public void print(Object o) { indent += 1; if (o is XPathStringLiteral) { XPathStringLiteral x = (XPathStringLiteral)o; printStr("strlit {" + x.s + "}"); } else if (o is XPathNumericLiteral) { XPathNumericLiteral x = (XPathNumericLiteral)o; printStr("numlit {" + x.d + "}"); } else if (o is XPathVariableReference) { XPathVariableReference x = (XPathVariableReference)o; printStr("var {" + x.id.ToString() + "}"); } else if (o is XPathArithExpr) { XPathArithExpr x = (XPathArithExpr)o; String op = null; switch (x.op) { case XPathArithExpr.ADD: op = "add"; break; case XPathArithExpr.SUBTRACT: op = "subtr"; break; case XPathArithExpr.MULTIPLY: op = "mult"; break; case XPathArithExpr.DIVIDE: op = "div"; break; case XPathArithExpr.MODULO: op = "mod"; break; } printStr(op + " {{"); print(x.a); printStr(" } {"); print(x.b); printStr("}}"); } else if (o is XPathBoolExpr) { XPathBoolExpr x = (XPathBoolExpr)o; String op = null; switch (x.op) { case XPathBoolExpr.AND: op = "and"; break; case XPathBoolExpr.OR: op = "or"; break; } printStr(op + " {{"); print(x.a); printStr(" } {"); print(x.b); printStr("}}"); } else if (o is XPathCmpExpr) { XPathCmpExpr x = (XPathCmpExpr)o; String op = null; switch (x.op) { case XPathCmpExpr.LT: op = "lt"; break; case XPathCmpExpr.LTE: op = "lte"; break; case XPathCmpExpr.GT: op = "gt"; break; case XPathCmpExpr.GTE: op = "gte"; break; } printStr(op + " {{"); print(x.a); printStr(" } {"); print(x.b); printStr("}}"); } else if (o is XPathEqExpr) { XPathEqExpr x = (XPathEqExpr)o; String op = x.equal ? "eq" : "neq"; printStr(op + " {{"); print(x.a); printStr(" } {"); print(x.b); printStr("}}"); } else if (o is XPathUnionExpr) { XPathUnionExpr x = (XPathUnionExpr)o; printStr("union {{"); print(x.a); printStr(" } {"); print(x.b); printStr("}}"); } else if (o is XPathNumNegExpr) { XPathNumNegExpr x = (XPathNumNegExpr)o; printStr("neg {"); print(x.a); printStr("}"); } else if (o is XPathFuncExpr) { XPathFuncExpr x = (XPathFuncExpr)o; if (x.args.Length == 0) { printStr("func {" + x.id.ToString() + ", args {none}}"); } else { printStr("func {" + x.id.ToString() + ", args {{"); for (int i = 0; i < x.args.Length; i++) { print(x.args[i]); if (i < x.args.Length - 1) { printStr(" } {"); } } printStr("}}}"); } } else if (o is XPathPathExpr) { XPathPathExpr x = (XPathPathExpr)o; String init = null; switch (x.init_context) { case XPathPathExpr.INIT_CONTEXT_ROOT: init = "root"; break; case XPathPathExpr.INIT_CONTEXT_RELATIVE: init = "relative"; break; case XPathPathExpr.INIT_CONTEXT_EXPR: init = "expr"; break; } printStr("path {init-context:" + init + ","); if (x.init_context == XPathPathExpr.INIT_CONTEXT_EXPR) { printStr(" init-expr:{"); print(x.filtExpr); printStr(" }"); } if (x.steps.Length == 0) { printStr(" steps {none}"); printStr("}"); } else { printStr(" steps {{"); for (int i = 0; i < x.steps.Length; i++) { print(x.steps[i]); if (i < x.steps.Length - 1) { printStr(" } {"); } } printStr("}}}"); } } else if (o is XPathFilterExpr) { XPathFilterExpr x = (XPathFilterExpr)o; printStr("filter-expr:{{"); print(x.x); if (x.predicates.Length == 0) { printStr(" } predicates {none}}"); } else { printStr(" } predicates {{"); for (int i = 0; i < x.predicates.Length; i++) { print(x.predicates[i]); if (i < x.predicates.Length - 1) { printStr(" } {"); } } printStr(" }}}"); } } else if (o is XPathStep) { XPathStep x = (XPathStep)o; String axis = null; String test = null; axis = XPathStep.axisStr(x.axis); test = x.testStr(); if (x.predicates.Length == 0) { printStr("step {axis:" + axis + " test:" + test + " predicates {none}}"); } else { printStr("step {axis:" + axis + " test:" + test + " predicates {{"); for (int i = 0; i < x.predicates.Length; i++) { print(x.predicates[i]); if (i < x.predicates.Length - 1) { printStr(" } {"); } } printStr("}}}"); } } indent -= 1; }