//very similar to parent(), but assumes contextRef refers to a singular, existing node in the model //this means we can do '/a/b/c + ../../d/e/f = /a/d/e/f', which we couldn't do in parent() //return null if context ref is not absolute, or we parent up past the root node //NOTE: this function still works even when contextRef contains INDEX_UNBOUND multiplicites... conditions depend on this behavior, // even though it's slightly icky public TreeReference anchor(TreeReference contextRef) { if (isAbsolute()) { return(this.clone()); } else if (!contextRef.isAbsolute()) { return(null); } else { TreeReference newRef = contextRef.clone(); int contextSize = contextRef.size(); if (refLevel > contextSize) { return(null); //tried to do '/..' } else { for (int i = 0; i < refLevel; i++) { newRef.removeLastLevel(); } for (int i = 0; i < size(); i++) { newRef.add(this.getName(i), this.getMultiplicity(i)); } return(newRef); } } }
//return a new reference that is this reference anchored to a passed-in parent reference //if this reference is absolute, return self //if this ref has 'parent' steps (..), it can only be anchored if the parent ref is a relative ref consisting only of other 'parent' steps //return null in these invalid situations public TreeReference parent(TreeReference parentRef) { if (isAbsolute()) { return(this); } else { TreeReference newRef = parentRef.clone(); if (refLevel > 0) { if (!parentRef.isAbsolute() && parentRef.size() == 0) { parentRef.refLevel += refLevel; } else { return(null); } } for (int i = 0; i < names.Count; i++) { newRef.add(this.getName(i), this.getMultiplicity(i)); } return(newRef); } }
//return a new reference that is this reference anchored to a passed-in parent reference //if this reference is absolute, return self //if this ref has 'parent' steps (..), it can only be anchored if the parent ref is a relative ref consisting only of other 'parent' steps //return null in these invalid situations public virtual TreeReference parent(TreeReference parentRef) { if (Absolute) { return(this); } else { TreeReference newRef = parentRef.Clone(); if (refLevel > 0) { if (!parentRef.Absolute && parentRef.size() == 0) { parentRef.refLevel += refLevel; } else { return(null); } } for (TreeReferenceLevel l: data) { newRef.add(l.shallowCopy()); } return(newRef); } }
/** * clone and extend a reference by one level * @param ref * @param name * @param mult * @return */ public TreeReference extendRef(String name, int mult) { //TODO: Shouldn't work for this if this is an attribute ref; TreeReference childRef = this.clone(); childRef.add(name, mult); return(childRef); }
//return a copy of the ref public TreeReference clone() { TreeReference newRef = new TreeReference(); newRef.setRefLevel(this.refLevel); for (int i = 0; i < this.size(); i++) { newRef.add(this.getName(i), this.getMultiplicity(i)); } return(newRef); }
public TreeReference relativize(TreeReference parent) { if (parent.isParentOf(this, false)) { TreeReference relRef = selfRef(); for (int i = parent.size(); i < this.size(); i++) { relRef.add(this.getName(i), INDEX_UNBOUND); } return(relRef); } else { return(null); } }
//return a copy of the ref //UPGRADE_ISSUE: The equivalent in .NET for method 'java.lang.Object.clone' returns a different type. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1224'" public virtual System.Object Clone() { TreeReference newRef = new TreeReference(); newRef.RefLevel = this.refLevel; for (TreeReferenceLevel l: data) { newRef.add(l.shallowCopy()); } //copy instances newRef.InstanceName = instanceName; newRef.Context = this.contextType; return(newRef); }
//very similar to parent(), but assumes contextRef refers to a singular, existing node in the model //this means we can do '/a/b/c + ../../d/e/f = /a/d/e/f', which we couldn't do in parent() //return null if context ref is not absolute, or we parent up past the root node //NOTE: this function still works even when contextRef contains INDEX_UNBOUND multiplicites... conditions depend on this behavior, // even though it's slightly icky public virtual TreeReference anchor(TreeReference contextRef) { //TODO: Technically we should possibly be modifying context stuff here //instead of in the xpath stuff; if (Absolute) { return(this.Clone()); } else if (!contextRef.Absolute) { throw new XPathException("Could not resolve " + this.toString(true)); } else { TreeReference newRef = contextRef.Clone(); int contextSize = contextRef.size(); if (refLevel > contextSize) { //tried to do '/..' throw new XPathException("Could not resolve " + this.toString(true)); } else { for (int i = 0; i < refLevel; i++) { newRef.removeLastLevel(); } for (int i = 0; i < size(); i++) { newRef.add(data.elementAt(i).shallowCopy()); } return(newRef); } } }