|
31 | 31 | import net.sf.saxon.s9api.SaxonApiException; |
32 | 32 | import net.sf.saxon.s9api.SequenceType; |
33 | 33 | import net.sf.saxon.s9api.XdmValue; |
| 34 | +import org.apache.jena.query.Query; |
34 | 35 | import org.apache.jena.query.QueryExecution; |
35 | | -import org.apache.jena.query.QuerySolutionMap; |
| 36 | +import org.apache.jena.query.QueryFactory; |
36 | 37 | import org.apache.jena.rdf.model.Model; |
| 38 | +import org.apache.jena.sparql.core.Var; |
| 39 | +import org.apache.jena.sparql.engine.binding.Binding; |
| 40 | +import org.apache.jena.sparql.engine.binding.BindingFactory; |
| 41 | +import org.apache.jena.sparql.expr.ExprVar; |
| 42 | +import org.apache.jena.sparql.syntax.ElementBind; |
| 43 | +import org.apache.jena.sparql.syntax.ElementGroup; |
37 | 44 | import org.apache.jena.rdf.model.ModelFactory; |
38 | 45 | import org.apache.jena.rdf.model.Resource; |
39 | 46 | import org.apache.jena.rdf.model.ResourceFactory; |
@@ -94,13 +101,24 @@ public XdmValue call(XdmValue[] arguments) throws SaxonApiException |
94 | 101 | arguments[0].itemAt(0).asMap().forEach((forClass, constructors) -> |
95 | 102 | { |
96 | 103 | Resource instance = model.createResource(); |
97 | | - QuerySolutionMap qsm = new QuerySolutionMap(); |
98 | | - qsm.add(SPIN.THIS_VAR_NAME, instance); |
99 | | - |
100 | 104 | instance.addProperty(RDF.type, ResourceFactory.createResource(forClass.getStringValue())); |
| 105 | + |
| 106 | + // Inject BIND(?_this_bind AS ?this) into the WHERE clause. |
| 107 | + // This keeps ?this as a variable in the CONSTRUCT template (not a written blank node), |
| 108 | + // so the template picks up the concrete node value — preserving blank node identity. |
| 109 | + // See: https://github.com/apache/jena/issues/3267 |
| 110 | + Var bindVar = Var.alloc("_this_bind"); |
| 111 | + Binding binding = BindingFactory.binding(bindVar, instance.asNode()); |
| 112 | + |
101 | 113 | constructors.stream().forEach(constructor -> |
102 | 114 | { |
103 | | - try (QueryExecution qex = QueryExecution.model(model).query(constructor.getStringValue()).initialBinding(qsm).build()) |
| 115 | + Query query = QueryFactory.create(constructor.getStringValue()); |
| 116 | + ElementGroup group = new ElementGroup(); |
| 117 | + group.addElement(query.getQueryPattern()); |
| 118 | + group.addElement(new ElementBind(Var.alloc(SPIN.THIS_VAR_NAME), new ExprVar(bindVar))); |
| 119 | + query.setQueryPattern(group); |
| 120 | + |
| 121 | + try (QueryExecution qex = QueryExecution.create().query(query).model(model).substitution(binding).build()) |
104 | 122 | { |
105 | 123 | qex.execConstruct(model); |
106 | 124 | } |
|
0 commit comments