Skip to content

Commit

Permalink
Favor predicates over multiplicity when contextualizing
Browse files Browse the repository at this point in the history
JR makes a distinction between predicates and multiplicity but really multiplicity should just be a position predicate. It doesn't make sense to have both a multiplicity and a predicate at a particular reference step. If that would happen, favor the predicate.
  • Loading branch information
lognaturel committed Jun 20, 2020
1 parent e95ef85 commit 5057f2c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,14 @@ public TreeReference contextualize(TreeReference contextRef) {
}

if (contextRef.getName(i).equals(newRef.getName(i))) {
if (newRef.getPredicate(i) == null) {
if (newRef.getPredicate(i) == null && contextRef.getPredicate(i) != null) {
// Positive integer multiplicity is equivalent to a predicate with a position expression so a
// reference level shouldn't have both. If there's an explicit predicate on either reference, always
// favor that and clear out multiplicity on the contextualized node.
newRef.addPredicate(i, contextRef.getPredicate(i));
newRef.setMultiplicity(i, INDEX_UNBOUND);
}
if (i + refLevel <= newRef.size()) {
if (newRef.getPredicate(i) == null && i + refLevel <= newRef.size()) {
newRef.setMultiplicity(i, contextRef.getMultiplicity(i));
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,30 @@ public class TreeReferenceContextualizeTest {
@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
// Self references
{"Relative context ref", getRef("bar"), getRef("foo"), null},
{"Non-matching absolute refs", getRef("/foo"), getRef("/bar"), getRef("/foo")},

{"Contextualizing a ref with itself and multiplicity #1", getRef("/foo"), getRef("/foo[2]"), getRef("/foo[2]")},
{"Contextualizing a ref with itself and multiplicity #2", getRef("/foo[-1]"), getRef("/foo[2]"), getRef("/foo[2]")},
{"Contextualizing a ref with itself and multiplicity #3", getRef("/foo[0]"), getRef("/foo[2]"), getRef("/foo[2]")},
{"Contextualizing a ref with itself and multiplicity #4", getRef("/foo[3]"), getRef("/foo[2]"), getRef("/foo[2]")},

{"Contextualizing a ref with itself and predicate #1", getRef("/foo"), getRef("/foo[position() = 3]"), getRef("/foo[position() = 3]")},
{"Contextualizing a ref with itself and predicate #2", getRef("/foo[position() = 2]"), getRef("/foo[position() = 3]"), getRef("/foo[position() = 2]")},

{"Contextualizing a ref with predicate with itself and multiplicity", getRef("/foo[position() = 2]"), getRef("/foo[1]"), getRef("/foo[position() = 2]")},
{"Contextualizing a ref with multiplicity with itself and predicate", getRef("/foo[1]"), getRef("/foo[position() = 2]"), getRef("/foo[position() = 2]")},

{"Wildcards #1", getRef("bar"), getRef("/foo/*"), getRef("/foo/*/bar")},
{"Wildcards #2", getRef("../baz"), getRef("/foo/*/bar"), getRef("/foo/*/baz")},
{"Wildcards #3", getRef("*/baz"), getRef("/foo/*/bar"), getRef("/foo/*/bar/*/baz")},
{"Wildcards #4", getRef("*/bar"), getRef("/foo"), getRef("/foo/*/bar")},

{"Predicates #1", getRef("bar"), getRef("/foo[@foo = 'bar']"), getRef("/foo[@foo = 'bar']/bar")},
{"Predicates #2", getRef("bar[@foo = 'baz']"), getRef("/foo[@foo = 'bar']"), getRef("/foo[@foo = 'bar']/bar[@foo = 'baz']")},
{"Predicates #3", getRef("bar[@foo = 'baz']"), getRef("/foo"), getRef("/foo/bar[@foo = 'baz']")},
{"Predicates #4", getRef("/foo[@foo = 'foo']"), getRef("/foo[@foo = 'bar']"), getRef("/foo[@foo = 'foo']")},

{"Parent refs in nested repeats", getRef("../../inner"), getRef("/data/outer[0]/inner[1]/count[0]"), getRef("/data/outer[0]/inner")}
});
}
Expand Down

0 comments on commit 5057f2c

Please sign in to comment.