BH14.14/XML2RDF

提供:TogoWiki

移動: 案内, 検索

BH14.14

既存のXMLデータのRDFへの変換

目次

背景

  • XML形式でデータが蓄積している
  • RDFになるべく自動で変換したい


  • XML関連技術で変換を行うと、XMLデータの提供者・利用者にも受け入れられやすいかもしれない

Possible Solutions

(1) 一般的な言語で、XMLをパースしてRDFに変換する

  • (1-1) 変換ルールをコーディングする
  • (1-2) 変換ルールは外から与える

(2) XSLTで変換コードを書く

(3) XSLTコードの生成を支援する

  • (3-1) XSLTより簡単な記法で書く(自前の記法、RDF形式(Turtle等)、XML
  • (3-2) XMLデータに関する既存のスタイルシートからXSLTコードを生成する
    • (3-2-1) XSLT コードの生成を一般的な言語で書く
    • (3-2-2) XSLT コードの生成も XSLT で書く

(1) 一般的な言語で変換コードを書く

変換ルールをコーディングする

目の前の問題をとにかく処理しようとすると、結局これになってしまう


OrthoXML example

Perlの XML:Simple モジュールを使ってパースして、Turtle形式に変換した

変換ルールは外から与える

現実的には、これが望ましい気がする


SWITがこれを実現しているように思える

しかし、コマンドでないのが惜しい

また、生成されたRDFを厳密にチェックをしているせいか、変換に時間がかかりすぎる

(2) XSLTで変換コードを書く

簡単な例

XSL Transformation (Wikipedia) にある XML の例

<?xml version="1.0" ?>
<persons>
  <person username="JS1">
    <name>John</name>
    <family-name>Smith</family-name>
  </person>
  <person username="MI1">
    <name>Morka</name>
    <family-name>Ismincius</family-name>
  </person>
</persons>

Turtleに変換するための XSLT を書いてみた

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
  <xsl:output method="text" encoding="UTF-8"/>
  
  <xsl:template match="/">
    <xsl:text>@prefix : &lt;http://example.org/&gt; .&#10;</xsl:text>
    <xsl:text>@prefix foaf: &lt;http://xmlns.com/foaf/0.1/&gt; .&#10;</xsl:text>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="persons/person" />
  </xsl:template>
 
  <xsl:template match="persons/person">
    <xsl:text>:</xsl:text> <xsl:value-of select="@username" /> <xsl:text>&#10;</xsl:text>
    <xsl:text>    a foaf:Person ;&#10;</xsl:text>
    <xsl:apply-templates select="*" />
  </xsl:template>
 
  <xsl:template match="name">
    <xsl:text>    foaf:firstName "</xsl:text> <xsl:value-of select="."/> <xsl:text>" ;&#10;</xsl:text>
  </xsl:template>
 
  <xsl:template match="family-name">
    <xsl:text>    foaf:familyName "</xsl:text> <xsl:value-of select="." /> <xsl:text>" .&#10;</xsl:text>
  </xsl:template>
 
</xsl:stylesheet>

Turtle に変換した結果

@prefix : <http://example.org/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

:JS1
    a foaf:Person ;
    foaf:firstName "John" ;
    foaf:familyName "Smith" .
:MI1
    a foaf:Person ;
    foaf:firstName "Morka" ;
    foaf:familyName "Ismincius" .

CellDesignerのXML(SBML)の例

まずはお決まりの部分です。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:s="http://www.sbml.org/sbml/level2/version4"
  xmlns:cd="http://www.sbml.org/2001/ns/cd"
  xmlns:date="http://exslt.org/dates-and-times"
  extension-element-prefixes="date">  
  <xsl:output method="text" encoding="UTF-8"/>

変換開始

  • まず、template match="xpath" を使ってエンティティの subject となるXML要素まで辿ります。
  • 次に、value-of select="要素 or 属性" を使って subject を指定します。要素なら <path>/. のように、属性なら <path>/@metaid のように書きます。
  • predicate はおそらく(XML内から取ってくるのではなく)直書きでしょうから、xsl:text で囲んで書いてしまいます。名前空間も同じです。
  • object は subject と同じように value-of select="要素 or 属性" で指定します。セミコロンで閉じて、&#10; で改行します。
  • この XML 要素の下の階層には、他のトリプルがあるかもしれません。その場合は apply-templates select="xpath" を宣言しておきます。
  <xsl:template match="/s:sbml/s:model">
    <xsl:text>cd:</xsl:text><xsl:value-of select="."/><xsl:text>;&#10;</xsl:text>
    <xsl:text>  a s:model ;&#10;</xsl:text>
    <xsl:text>  cd:metaid "</xsl:text><xsl:value-of select="@metaid" /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:model_version "</xsl:text><xsl:value-of select="s:annotation/cd:extension/cd:modelVersion/." /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:model_display_size_x "</xsl:text><xsl:value-of select="s:annotation/cd:extension/cd:modelDisplay/@sizeX" /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:model_display_size_y "</xsl:text><xsl:value-of select="s:annotation/cd:extension/cd:modelDisplay/@sizeY" /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  .&#10;</xsl:text>
    <xsl:apply-templates select="s:listOfSpecies/s:species" />
    <xsl:apply-templates select="s:listOfReactions/s:reaction" />
  </xsl:template>

apply-templates select="xpath" で宣言したエンティティについて同じように書きます。

  <xsl:template match="s:listOfSpecies/s:species">
    <xsl:text>cd:</xsl:text><xsl:value-of select="@id" /><xsl:text>&#10;</xsl:text>
    <xsl:text>  a cd:species ;&#10;</xsl:text>
    <xsl:text>  cd:metaid "</xsl:text><xsl:value-of select="@metaid" /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:name "</xsl:text><xsl:value-of select="@name" /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:compartment "</xsl:text><xsl:value-of select="@compartment" /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:initialAmount "</xsl:text><xsl:value-of select="@initialAmount" /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:position_to_compartment "</xsl:text><xsl:value-of select="s:annotation/cd:extension/cd:positionToCompartment/." /><xsl:text>" ;&#10;</xsl:text>
    <xsl:text>  cd:class cd:</xsl:text><xsl:value-of select="s:annotation/cd:extension/cd:speciesIdentity/cd:class/." /><xsl:text> ;&#10;</xsl:text>
    <xsl:apply-templates select="s:annotation/cd:extension/cd:speciesIdentity/cd:proteinReference" /
    <xsl:text>  .&#10;</xsl:text>
  </xsl:template>

閉じます

</xsl:stylesheet>

おまけ、後で書く

  <!-- SET MAP ID -->
  <xsl:variable name="map_id" select="concat(/s:sbml/s:model/@id, '-', date:date-time())"/>
  
  <xsl:strip-space elements="s:sbml"/>

XSLTの実行方法

XSLTプロセッサに、XMLデータファイルと、XSLTファイルを与えると、変換した結果が得られる。

Node.js の場合

まずはnode.jsをインストール -- http://nodejs.org/download/

XSLTエンジンをインストール

$ npm install node_xslt

変換用スクリプト xslt.js は次の通り

$ vi xslt.js
xslt = require('node_xslt')
var args = process.argv;
stylesheet = xslt.readXsltFile(args[2]);
document = xslt.readXmlFile(args[3]);
transformedString = xslt.transform(stylesheet, document, []);
console.log(transformedString);

がんばってmapping.xslを書く!

これを使って一発でXMLをTurtleに変換する

$ node xslt.js mapping.xsl in.xml > out.ttl

N-triples で見たかったら Jena で変換しよう

$ rdfcat -n out.ttl -out N-TRIPLE > out.nt

Fuseki でエンドポイントを起動しよう

$ ./fuseki-server --update --file=/Users/Ryota/Sites/linked-pathway/rdfize/data/sample01.ttl /ds
http://localhost:3030/ にアクセス

SAXONの場合

SAXON (by Michael Kay, Saxonica Ldt.)

java -cp path/to/saxon.jar com.icl.saxon.StyleSheet example.xml example.xsl

(3) XSLTの生成を支援する

自前の記法で変換ルール記述する

例:

@prefix : <http://example.org/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<persons>

<person username>
  a foaf:Person
  <name>
  <family-name>

<name>
  foaf:firstName "" ;

<family-name>
  foaf:familyName "" .

これをPerlスクリプトでXSLTに変換する

自前のRDFモデルで変換ルールを記述する

自前のXML形式で変換ルールを記述する

既存のスタイルシート等からXSLTを生成する

References

ReDeFerに言及している記事

ReDeFer

ReDeFerはけっこういい線いっているのではないか

単純で、小さなデータは、普通に変換できている

curl等でWeb APIをたたける


ただし、課題としては

  • 複雑なもの
  • 大きなデータ

をちゃんと処理するということができるのかどうか


やはり、

  • mappingファイルの記述
  • リソースURI を作るための prefix の指定

などを、細かく制御しないと、複雑なものはうまく処理できないだろう


あと、大きなデータの処理なら、コマンドになってないと使いにくい

入力ファイルが、Web上で公開されてないといけない

Ideas

XMLの取り回しに関しては、Scalaで書くといいのかもしれない

XML/RDF変換が動的にできれば、XMLデータベースに対して、SPARQLで検索可能になるのだろうか?

XSPARQL

XML内でのエスケープ処理

文字 エスケープシーケンス
< &lt;
> &gt;
& &amp;
" &quot;
' &apos;
/mw/BH14.14/XML2RDF」より作成