2013-07-18 1 views
0

У меня есть данные RDF/XML, которые я хотел бы проанализировать и получить доступ к узлу. Это выглядит следующим образом:Доступ к узлам файлов RDF/XML/OWL с использованием Perl

<!-- http://purl.obolibrary.org/obo/VO_0000185 --> 

    <owl:Class rdf:about="&obo;VO_0000185"> 
     <rdfs:label>Influenza virus gene</rdfs:label> 
     <rdfs:subClassOf rdf:resource="&obo;VO_0000156"/> 
     <obo:IAO_0000117>YH</obo:IAO_0000117> 
    </owl:Class> 



    <!-- http://purl.obolibrary.org/obo/VO_0000186 --> 

    <owl:Class rdf:about="&obo;VO_0000186"> 
     <rdfs:label>RNA vaccine</rdfs:label> 
     <owl:equivalentClass> 
      <owl:Class> 
       <owl:intersectionOf rdf:parseType="Collection"> 
        <rdf:Description rdf:about="&obo;VO_0000001"/> 
        <owl:Restriction> 
         <owl:onProperty rdf:resource="&obo;BFO_0000161"/> 
         <owl:someValuesFrom rdf:resource="&obo;VO_0000728"/> 
        </owl:Restriction> 
       </owl:intersectionOf> 
      </owl:Class> 
     </owl:equivalentClass> 
     <rdfs:subClassOf rdf:resource="&obo;VO_0000001"/> 
     <obo:IAO_0000116>Using RNA may eliminate the problem of having to tailor a vaccine for each individual patient with their specific immunity. The advantage of RNA is that it can be used for all immunity types and can be taken from a single cell. DNA vaccines need to produce RNA which then prompts the manufacture of proteins. However, RNA vaccine eliminates the step from DNA to RNA.</obo:IAO_0000116> 
     <obo:IAO_0000115>A vaccine that uses RNA(s) derived from a pathogen organism.</obo:IAO_0000115> 
     <obo:IAO_0000117>YH</obo:IAO_0000117> 
    </owl:Class> 

Полный RDF/XML файл можно найти here.

То, что я хочу сделать, это сделать следующее:

  1. Find кусок, где содержится запись <rdfs:subClassOf rdf:resource="&obo;VO_0000001"/>
  2. Доступ буквальный термин, как это определено <rdfs:label>...</rdfs:label>

Таким образом, в выше Например, код будет проходить второй кусок и вывод: «РНК-вакцина».

В настоящее время я придерживаюсь следующего кода. Где я не мог получить доступ к узлу. Каков правильный способ сделать это? Приветствуются решения, отличные от использования XML :: LibXML .

#!/usr/bin/perl -w 
use strict; 
use Data::Dumper; 
use Carp; 
use File::Basename; 
use XML::LibXML 1.70; 

my $filename = "VO.owl"; 
# Obtained from http://svn.code.sf.net/p/vaccineontology/code/trunk/src/ontology/VO.owl 

my $parser = XML::LibXML->new(); 
my $doc = $parser->parse_file($filename); 

foreach my $chunk ($doc->findnodes('/owl:Class')) { 
     my ($label) = $chunk->findnodes('./rdfs:label'); 
     my ($subclass) = $chunk->findnodes('./rdfs:subClassOf'); 
     print $label->to_literal; 
     print $subclass->to_literal; 

} 
+1

Я бы упомянул, что не только приветствуются решения, не использующие библиотеки XML, а _preferred_; [не пытайтесь разобрать RDF как XML] (http://stackoverflow.com/a/17052385/1281433). Это правда, что RDF может быть сериализован в XML, но один и тот же график RDF может быть сериализован в XML в нескольких разных вариантах_, а решение XML, которое работает на одном, вряд ли будет работать на другом. RDF является представлением _graph-based_ и должно рассматриваться как таковое. –

ответ

3

Разбор RDF, как будто это был XML, является глупостью. Точные данные могут отображаться разными способами. Например, все следующие RDF-файлы имеют одинаковые данные. Любое Соответствующая реализация RDF ДОЛЖЕН обращаться с ними одинаково ...

<!-- example 1 --> 
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
    <rdf:Description rdf:about="#me"> 
    <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person" /> 
    <foaf:name>Toby Inkster</foaf:name> 
    </rdf:Description> 
</rdf:RDF> 

<!-- example 2 --> 
<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:foaf="http://xmlns.com/foaf/0.1/"> 
    <foaf:Person rdf:about="#me"> 
    <foaf:name>Toby Inkster</foaf:name> 
    </foaf:Person> 
</rdf:RDF> 

<!-- example 3 --> 
<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:foaf="http://xmlns.com/foaf/0.1/"> 
    <foaf:Person rdf:about="#me" foaf:name="Toby Inkster" /> 
</rdf:RDF> 

<!-- example 4 --> 
<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:foaf=""> 
    <rdf:Description rdf:about="#me" 
    rdf:type="http://xmlns.com/foaf/0.1/Person" 
    foaf:name="Toby Inkster" /> 
</rdf:RDF> 

<!-- example 5 --> 
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
    <rdf:Description rdf:ID="me"> 
    <rdf:type> 
     <rdf:Description rdf:about="http://xmlns.com/foaf/0.1/Person" /> 
    </rdf:type> 
    <foaf:name>Toby Inkster</foaf:name> 
    </rdf:Description> 
</rdf:RDF> 

<!-- example 6 --> 
<foaf:Person 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:foaf="http://xmlns.com/foaf/0.1/" 
    rdf:about="#me" 
    foaf:name="Toby Inkster" /> 

Я мог бы легко перечислить полдюжины других вариантов, но я буду останавливаться на достигнутом. И этот файл RDF содержит только два утверждения - я человек; меня зовут «Тоби Инкстер» - данные ОП содержат более 50 000 заявлений.

И это всего лишь XML-сериализация RDF; есть и другие сериализации.

Если вы попробуете обработать все это с помощью XPath, вы, вероятно, окажетесь сумасшедшим, запертым в башне где-то, бормоча во сне о троек; тройки ...

К счастью, Грег Уильямс взял для вас эту пулю психического здоровья. RDF::Trine и RDF::Query - это не только лучшие рамки RDF для Perl; они являются одними из лучших на любом языке программирования.

Вот как задача OP могла быть достигнута с помощью RDF :: Трина и RDF :: Query: выход

#!/usr/bin/env perl 

use v5.12; 
use RDF::Trine; 
use RDF::Query; 

my $model = 'RDF::Trine::Model'->new(
    'RDF::Trine::Store::DBI'->new(
     'vo', 
     'dbi:SQLite:dbname=/tmp/vo.sqlite', 
     '', # no username 
     '', # no password 
    ), 
); 

'RDF::Trine::Parser::RDFXML'->new->parse_url_into_model(
    'http://svn.code.sf.net/p/vaccineontology/code/trunk/src/ontology/VO.owl', 
    $model, 
) unless $model->size > 0; 

my $query = RDF::Query->new(<<'SPARQL'); 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
SELECT ?super_label ?sub_label 
WHERE { 
    ?sub rdfs:subClassOf ?super . 
    ?sub rdfs:label ?sub_label . 
    ?super rdfs:label ?super_label . 
} 
LIMIT 5 
SPARQL 

print $query->execute($model)->as_string; 

Пример:

+----------------------------+----------------------------------+ 
| super_label    | sub_label      | 
+----------------------------+----------------------------------+ 
| "Aves vaccine"    | "Ducks vaccine"     | 
| "route of administration" | "intravaginal route"    | 
| "Shigella gene"   | "aroA from Shigella"    | 
| "Papillomavirus vaccine" | "Bovine papillomavirus vaccine" | 
| "virus protein"   | "Feline leukemia virus protein" | 
+----------------------------+----------------------------------+ 

UPDATE: Вот запрос SPARQL, что могут быть подключены к приведенному выше сценарию, чтобы получить нужные данные:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX obo: <http://purl.obolibrary.org/obo/> 
SELECT ?subclass ?label 
WHERE { 
    ?subclass 
     rdfs:subClassOf obo:VO_0000001 ; 
     rdfs:label ?label . 
} 
+0

Спасибо за объяснение. Я обычно стараюсь держаться подальше от XML, и есть некоторые XML-технологии, которые я особенно стараюсь избегать (например, XSD, SOAP). RDF будет добавлен в этот список :-) –

+1

Вы, конечно же, не должны добавлять RDF в список технологий XML, которых вы хотите избежать. Избегайте его, если хотите; хорошо. Но (несмотря на сериализацию XML) это не технология XML, поэтому вы бы поместили ее в неправильный список. – tobyink

+0

@tobyink: Спасибо. Но как я могу гарантировать, что вывод метки является подклассом VO_0000001. – neversaint

2

/owl:Class не является корневым элементом вашего XML-документа. Вы должны включить корневой элемент в ваш XPath: /rdf:RDF/owl:Class. Или, если вы хотите получить все вхождения, независимо от глубины в дереве XML, вы можете использовать обозначение с двойной косой чертой: //owl:Class.

+0

Спасибо Славен. Но я не могу получить доступ к содержимому «subClassOf». Какая для этого правильная команда? – neversaint

+1

Вы можете получить доступ к subClassOf. Но это не имеет буквального значения (это текстовое содержимое между тегами, поэтому оно выглядит как пустая строка. Вместо 'to_literal()' try 'serialize', чтобы увидеть, что он соответствует. –

+0

@neversaint Что такое подкласс? вы сказали, что пытаетесь получить доступ к значению свойств 'rdfs: label' классов, а затем также определить значения свойства' owl: subClassOf' для классов. Какой контент вы пытаетесь получить из подклассов ? –

3

Взгляните на сайт perlrdf.org, который содержит ссылки на несколько пакетов Perl для работы с RDF.

Использование этих, скорее всего, гораздо более гибких и менее подверженных ошибкам доступа к RDF/XML с использованием XPath, поскольку RDF/XML не является канонизированной сериализацией, то есть одни и те же данные могут быть представлены в разных форматах XML в зависимости от инструмента, используемого для сериализации Это.

 Смежные вопросы

  • Нет связанных вопросов^_^