• 品尝SPARQL系列之二 在.NET中跨平台调用Joseki的SPARQL Web Services


    在Joseki中,已经开发了SPARQL查询的Web Services,在Joseki3\src-soap\org\joseki\soap目录中。现在要说明的是如何在.NET平台上调用该Web Services。

    首先,如系列一所写的那样,先在Java平台上调用成功。

    跨平台调用的关键在于找到该Web Services的接口文件(WSDL)以及复杂类型的定义xsd文件,然后利用wsdl工具生成客户端代理类。由于SPARQL已经有相关的W3C建议文档,而Joseki是完全按照文档实现该协议的,下面的网址是SPARQL的HTTP绑定和SOAP绑定的协议文档:
    http://www.w3.org/TR/rdf-sparql-protocol/ 

    关于WSDL的版本问题

    在这个W3C文档中,可以找到sparql ws接口定义文件,其网址是http://www.w3.org/TR/rdf-sparql-protocol/sparql-protocol-query.wsdl是遵循http://www.w3.org/2006/01/wsdl所制定的WSDL2.0的,这个版本目前不被Visual Studio 2005自带的wsdl.exe工具支持,因此,需要将其修改成旧版本的wsdl。首先是缺省命名空间的改动,VS2005中缺省命名空间应该是:http://schemas.xmlsoap.org/wsdl/,否则wsdl.exe会报错的。另外,wsdl1.0中PortType在wsdl2.0中是interface,并且wsdl1.0中message的定义是在PortType前面的,总之,拿VS2005生成的任何一个wsdl文件和这个新版本的sparql-protocol-query.wsdl比较一下结构,改动还是不难的。

    生成客户端代理类

    在这个wsdl文件的<types>…</types>部分,是关于message中用到的复杂类型的Schema定义,当类型定义比较多时,可以将其分别放入不同的xsd文件中,而在wsdl中采用<import> 标签:
    <types>
       <xs:import namespace="http://www.w3.org/2005/09/sparql-protocol-types/#"
          schemaLocation="sparql-protocol-types.xsd"/>
    </types> 

    上面说的这个W3C文档还给出了http://www.w3.org/TR/rdf-sparql-protocol/sparql-protocol-types.xsd,里面是关于 sparql-request, sparql-result和定义。在这个xsd中又需要导入关于sparql result中几个元素的定义,下面的网址介绍了SPARQL的查询结果XML Format:http://www.w3.org/TR/rdf-sparql-XMLres/
    里面找到http://www.w3.org/TR/rdf-sparql-XMLres/result2.xsd

    因此,需要紧接着在<xs:schema targetNamespace="http://www.w3.org/2005/09/sparql-protocol-types/#"。。。。>之后加入
    <xs:import namespace="http://www.w3.org/1999/02/22-rdf-syntax-ns#" schemaLocation="rdf.xsd"/>  
    <xs:import namespace="http://www.w3.org/2005/sparql-results#" schemaLocation="result2.xsd"/> 
    而result2.xsd中,又需要加入:
    <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/> 

    现在,将sparql-protocol-query.wsdl和sparql-protocol-types.xsd/result2.xsd/xml.xsd/rdf.xsd放在同一个目录下,从Visual Studio Tools目录打开Visual Studio 2005 命令行工具,转到这几个文件所在目录键入如下命令:
    wsdl sparql-protocol-query.wsdl sparql-protocol-types.xsd result2.xsd xml.xsd rdf.xsd
    即生成出在.net平台下调用sparql WS的客户端代理类。

    跨平台调用及其返回结果

    在.net平台下用c#编写简单的程序调用sparql WS,查询的RDF数据源使用josek3/Data目录下的例子books.n3:

    @prefix dc:        <http://purl.org/dc/elements/1.1/> .
    @prefix vcard:     <http://www.w3.org/2001/vcard-rdf/3.0#> .
    @prefix ns:        <http://example.org/ns#> .
    @prefix :          <http://example.org/book/> . 

    :book1
        dc:title    "Harry Potter and the Philosopher's Stone" ;
        dc:creator  "J.K. Rowling" ;
        .  
    :book2
        dc:title    "Harry Potter and the Chamber of Secrets" ;
        dc:creator  _:a .  
    :book3
        dc:title    "Harry Potter and the Prisoner Of Azkaban" ;
        dc:creator  _:a .  
    :book4
        dc:title    "Harry Potter and the Goblet of Fire" . 
    :book5
        dc:title    "Harry Potter and the Order of the Phoenix".  
    :book6
        dc:title    "Harry Potter and the Half-Blood Prince".    
    _:a
        vcard:FN "J.K. Rowling" ;
        vcard:N
            [ vcard:Family "Rowling" ;
              vcard:Given "Joanna"
            ].

    SPARQL语句SELECT ?z {?x ?y ?z . FILTER regex(?z, 'Harry')},将返回所有value的前缀为harry的三元组。

    在java平台下打开org.apache.axis.utils.tcpmon可监视soap包的内容,注意tcpmon监听端口的设置和C#客户端设置的调用Web服务地址端口应该一致,而target port是Web服务的真实调用地址端口。这样,soap请求就先发送到监听端口,然后tcpmon截获该消息,同时将请求发送给target port,这样就可以既截获请求,又调用Web服务。

    例如,若Joseki3中sparql services的地址是:
    http://localhost:2525/axis/services/sparql-query
    则设置Listener的target hostname&port是127.0.0.1:2525,
    若设置Listen port是1234,则应该将wsdl.exe生成的客户端代理类中指定的web服务URL修改为
    http://localhost:1234/axis/services/sparql-query

    C#客户端调用Web服务
    String queryStr = "SELECT ?z{?x ?y ?z . FILTER regex(?z, 'Harry')}\n";
    SparqlQueryService service = new SparqlQueryService();
    sparql s = (sparql)service.query(queryStr, null, null); 

    其中sparql、results、item等是对应前面介绍的几个xsd中定义的复杂类型,要理解这几个类的数据结构,还是要回到sparql协议文档,看看SPARQL查询结果的XML格式:
    <sparql xmlns="http://www.w3.org/2005/sparql-results#">
      <head>
        <variable name="name"/>
      </head>
      <results ordered="false" distinct="false">
        <result>
          <binding name="name">
            <literal datatype="http://www.w3.org/2001/XMLSchema#string">
            </literal>
          </binding>
        </result>
       <!-- more results -->
       </results>
    </sparql>

    如同SQL的查询结果一样,SPARQL查询结果也是“行”“列”来构成的,这种格式通过使用XSLT就可以简单地转换为HTML格式的网页呈现出来。

    <head>标签中的内容是“列”(variable)的名字;而<results>标签包括数个<result>,每个result是一“行”,每“行”中内容是多个<binding name="name">,binding的名字属性对应列的名字,每个元素的内容可以是literal, bnode和uri。

    C#调用客户端代理类返回的sparql对象并不直观,因此,如同Joseki3中使用的com.hp.hpl.jena.query.Query命名空间中的ResultSet(继承自Iterator迭代类)一样,在C#中可以将其对结果的处理代码移植过来使用,调用WS而返回类似的ResultSet。

    好,示例程序已经说明,现在无论是在java平台还是.net平台,sparql调用的路途已经基本畅通了。下面,系列三将举几个更为实际一些的例子,说明一下SPARQL的用途。
  • 相关阅读:
    对现有Hive的大表进行动态分区
    Hive表分区
    Hive常用的SQL命令操作
    Hadoop分布式安装
    Hadoop命令摘录
    HDFS基本知识整理
    Hive基本命令整理
    Hadoop
    淘宝数据魔方技术架构解析
    Eclipse 下 opennms 开发环境搭建
  • 原文地址:https://www.cnblogs.com/Jacquette/p/sparql2.html
Copyright © 2020-2023  润新知