Hi Steve,
SPINMap has been designed to help people without a deep understanding of
SPIN or SPARQL to build mappings. It covers the most frequently needed
use cases, and provides a syntax that is suitable for graphical editing.
Like every such language with a simplified scope, the expressivity has
been intentionally cut down and not every possible use case of SPIN and
SPARQL is covered by SPINMap. You can now guess that my answer is that
you may need to bypass the SPINMap syntax for more complex cases like
the one that you describe - mapping one rdf:List with multiple target
values.
Fortunately, SPINMap is just an application of SPIN templates, and SPIN
templates can be executed with the same engine as any other SPIN rules.
This means that you can mix SPINMap with conventional "hand-coded" SPIN
rules.
On 7/20/2014 10:43, Steve Ray (CMU) wrote:
I have what I think must be a common problem:
Assume I have a source class with property A, and its value is a list
of strings.
I want to map this to a destination class with multiple instances of
property B, each derived from one of the strings in the list.
My problem is that SPINMap can only call functions, and a function can
only return a single value. To my knowledge, you cannot do something
tricky with magic properties in a SPINMap mapping, right? So defining
my own function doesn't help.
The only workaround I can think of is to just map it over using
spinmap:equals, and then write a SPIN rule for the destination class
that goes in and uses a pattern like
?list (rdf:rest)*/rdf:first ?item.
...to assert the individual items. This isn't very elegant, and in
fact I'm having trouble having the rule clean up after itself and
deleting the unwanted list without throwing itself into an infinite
loop, so I'm hoping I'm just unaware of some obvious approach to this.
(For what it's worth, my SPIN rule that ran on forever was the following)
# Convert lists of keywords to individual instances of keywords
*DELETE*{
*?this* or:hasKeyword ?listOrItem.
}
*INSERT*{
*?this* or:hasKeyword ?item.
}
*WHERE*{
*?this* or:hasKeyword ?listOrItem.
*FILTER* (!spl:instanceOf(?listOrItem, xsd:string)) .
?listOrItem (rdf:rest)*/rdf:first ?item.
}
What I'd really like is help with my initial problem, but if there's
no solution within SPINMap, then I guess I need help with my workaround.
The normal application area of SPINMap is to create new triples (in the
target ontology) out of existing triples (in the source ontology).
SPINMap for sure has not been designed to delete any triples - it just
adds new triples. In your code above, the DELETE may delete the root of
your rdfList, but not the intermediate blank nodes that constitute the
rdf:List internally. So you would end up with orphan nodes. I do not see
why it would run into an infinite loop though.
Sorry I don't have time to work out a complete solution for you right
now, maybe tomorrow (or someone else may help out).
Holger
--
-- You received this message because you are subscribed to the Google
Group "TopBraid Suite Users", the topics of which include Enterprise Vocabulary
Network (EVN), TopBraid Composer, TopBraid Live, TopBraid Insight, SPARQLMotion, SPARQL
Web Pages and SPIN.
To post to this group, send email to
[email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/topbraid-users?hl=en
---
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.