【问题标题】:Can't PREFIX hierarchies with SPARQL无法使用 SPARQL 为层次结构添加前缀
【发布时间】:2014-08-28 11:01:15
【问题描述】:

我需要像这样在我的 URL 中表示层次结构:

http://www.me.org/ -----------------root1/ - - - - - - - - - - - -1级/ ------------------level2/etc

我想定义 PREFIX 并在 SPARQL 查询中使用它们,如下所示:

前缀 root1: 选择 * 其中 { ?s ?p root1:level1/level2/etc 。 } 限制 100

这将在 ARQ 中失败并出现以下错误:

在第 10 行第 43 列遇到“”/“”/“”。 期待其中之一: “价值观”... “图表”... ...

我应该能够像这样在我的 URL 中表示层次结构,还是 SPARQL 和 PREFIX 的使用仅限于一个级别?

【问题讨论】:

    标签: rdf sparql jena arq


    【解决方案1】:

    4.1.1.1 Prefixed Names

    PREFIX 关键字将前缀标签与 IRI 相关联。一个前缀 name 是前缀标签和本地部分,用冒号“:”分隔。一种 前缀名称通过连接关联的 IRI 映射到 IRI 带有前缀和本地部分。前缀标签或本地部分 可能是空的。请注意,SPARQL 本地名称允许前导数字,而 XML 本地名称没有。 SPARQL 本地名称也允许 通过反斜杠字符在 IRI 中允许的非字母数字字符 转义(例如 ns:id\=123)。 SPARQL 本地名称具有更多语法 比 CURIE 的限制。

    让我们检查一下语法,看看\是否是假定的非字母数字字符之一:

    19.8 Grammar

    [169]     PN_LOCAL      ::=   (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
    [170]     PLX           ::=   PERCENT | PN_LOCAL_ESC
    [171]     PERCENT       ::=   '%' HEX HEX
    [172]     HEX           ::=   [0-9] | [A-F] | [a-f]
    [173]     PN_LOCAL_ESC  ::=   '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?'
    

    | '#' | '@' | '%')

    果然应该可以通过:

    PN_LOCAL → PLX → PN_LOCAL_ESC → '\' '/'

    这样你应该可以写:

    ?s ?p root1:level1\/level2\/element .
    

    【讨论】:

    • +1 只是输入了同样的东西,但你打败了我!
    • 我很欣赏对规范的回应。并且意味着您不能在没有前缀“\”的 esc 字符的情况下使用“/”。那么答案是您不能自然地在 SPARQL 中表示 URL 命名空间的层次结构。 @JoshuaTaylor。
    • @Interition 好吧,我想这取决于您是否认为用 a/b/c 而不是 a\/b\/c 来表示层次结构是自然的。目前尚不清楚使用两个字符来分隔“级别”是不自然的,而使用一个字符是自然的,但如果这是你的立场,那么不,没有自然的方法来做到这一点。
    • '/' 用于属性路径。 \/ 用于本地名称是很晚才添加的,当时进行了对齐 SPARQL 和 Turtle 的工作,并且 SPARQL-WG 的时间不多了。结果并不微妙。
    • @AndyS 冒着使本地名称规范复杂化的风险,属性路径仅出现在属性中,因此未来的规范可能允许 ex:a/b/c 用于主体和客体,但是需要 ex:a\/b\/c 属性?这似乎也有点笨拙。
    【解决方案2】:

    您可以在前缀声明中使用相对 URI:

    BASE <http://example/>
    PREFIX root1:  <root1/>
    PREFIX level1: <root1/level1/>
    PREFIX level2: <root1/level1/level2/>
    
    SELECT * {
      ?s ?p  level2:etc .
    }
    

    这避免了在 URI 中重复部分字符串的一些开销。

    【讨论】:

    • @RobV BASE 和多个 PREFIX 是选项,但我们的用例往往需要很多,这看起来像重复,不会很优雅。
    【解决方案3】:

    我认为问题在于 SPARQL/RDF 的价值主张是 WWW 的扩展,建立在 URI/URL 原则之上 通常被视为使用 / 作为命名空间分隔符,所以你不会 期望必须做一些特殊的事情来处理一个 URL

    您似乎将 URI 与前缀名称混为一谈,前缀名称是一种便利机制,旨在让您以更紧凑的形式写下 URI 以提高可读性。因此,如果不使用转义字符,它们就无法表示所有可能的 URI,否则在语法中会模棱两可。

    正如 Joshua Taylor 的回答所证明的那样(在您看来)的缺点是您不能按原样使用带有前缀名称的相对 URI,这仅仅是 SPARQL 和其他使用类似语法结构的 RDF 序列化的语法限制。

    但是,如果我们使用 BASE 指令,例如,我们可以自然地写下相对 URI 而无需使用任何特殊字符。

    BASE <http://www.me.org/root1/>
    
    SELECT *
    WHERE
    {
        ?s ?p <level1/level2/etc> .
    }
    LIMIT 100
    

    请注意,在这种情况下,我们必须将相对 URI 括在 &lt; &gt; 中,因为我们使用的是 URI 而不是前缀名称。如果 URI 是相对的,SPARQL 处理器将根据声明的 BASE 解析它,从而为您提供所需的完整 URI,而无需使用任何转义字符。

    这也许会给你一些你认为更自然的东西?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-27
      • 2012-05-31
      • 2022-08-25
      • 2013-07-06
      • 1970-01-01
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多