2016-05-05 5 views
2

XQueryを使用してXMLをRDF(RDF/XML構文)に変換しようとしています。XQuery:XMLをRDFに変換

declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 
declare namespace owl="http://www.w3.org/2002/07/owl#"; 
declare namespace xsd="http://www.w3.org/2001/XMLSchema#"; 
declare namespace rdfs="http://www.w3.org/2000/01/rdf-schema#"; 

import module namespace functx="http://www.functx.com"; 

declare variable $srcDoc:="test.xml"; 
declare variable $defaultXMLNS:="http://www.test.com#"; 
declare variable $defaultXMLBase:=$defaultXMLNS; 


declare function local:getQName($local as xs:string?) 
as xs:QName? 
{ 
    QName($defaultXMLNS, $local) 
}; 

declare function local:namedIndividualConstructor($pnode as node()*) 
as node()* 
{ 
    element owl:NamedIndividual 
    { 
    (:to avoid repeated names, unique uuid is generated for each individuals:) 
    attribute rdf:about {concat("#", random:uuid(), "_", $pnode/name())}, 
    element rdf:type {attribute rdf:resource {concat("#", $pnode/name())}}, 

    for $x in $pnode/* 
    return element {local:getQName(concat($pnode/name(), "_", $x/name()))} 
    { 
     attribute rdf:resource {} 
    } 

    } 
}; 

element rdf:RDF 
{ 
    namespace {""} {$defaultXMLNS}, 
    attribute xml:base {$defaultXMLBase}, 
    element owl:Ontology 
    { 
    attribute rdf:about {$defaultXMLNS} 
    }, 
    for $x in doc($srcDoc)//* 
    return if($x[not(child::*)]) 
    then() 
    (:only generate namedIndividual for nodes having leaf nodes:) 
    else local:namedIndividualConstructor($x) 
} 

のtest.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<breakfast_menu> 
<food> 
    <name>French Toast aaa</name> 
    <price>$5.95</price> 
    <description>Our famous Belgian Waffles with plenty of real maple syrup</description> 
    <calories>650</calories> 
</food> 
<food> 
    <name>French Toast</name> 
    <price>$4.50</price> 
    <description>Thick slices made from our homemade sourdough bread</description> 
    <calories>600</calories> 
</food> 
<food> 
    <name>Homestyle Breakfast</name> 
    <price>$6.95</price> 
    <description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description> 
    <calories>950</calories> 
</food> 
</breakfast_menu> 

コマンドライン:

basex -o testxqyoutput.rdf test.xqy 

testxqyoutput私は私が...

test.xqyを克服することができませんでした何かが発生したと思います。 rdf:

<rdf:RDF xmlns="http://www.test.com#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xml:base="http://www.test.com#"> 
    <owl:Ontology xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="http://www.test.com#"/> 
    <owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#82ab6f48-2faf-4782-840f-59e6e96403ef_breakfast_menu"> 
    <rdf:type rdf:resource="#breakfast_menu"/> 
    <breakfast_menu_food rdf:resource=""/> 
    <breakfast_menu_food rdf:resource=""/> 
    <breakfast_menu_food rdf:resource=""/> 
    </owl:NamedIndividual> 
    <owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#04f02acc-da19-47a7-a69a-98cc958efbbd_food"> 
    <rdf:type rdf:resource="#food"/> 
    <food_name rdf:resource=""/> 
    <food_price rdf:resource=""/> 
    <food_description rdf:resource=""/> 
    <food_calories rdf:resource=""/> 
    </owl:NamedIndividual> 
    <owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#bfec0a13-ac56-4ac8-a9bb-0575b16e601a_food"> 
    <rdf:type rdf:resource="#food"/> 
    <food_name rdf:resource=""/> 
    <food_price rdf:resource=""/> 
    <food_description rdf:resource=""/> 
    <food_calories rdf:resource=""/> 
    </owl:NamedIndividual> 
    <owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#7f6411cb-3619-4b61-8b78-3b1e8ec99898_food"> 
    <rdf:type rdf:resource="#food"/> 
    <food_name rdf:resource=""/> 
    <food_price rdf:resource=""/> 
    <food_description rdf:resource=""/> 
    <food_calories rdf:resource=""/> 
    </owl:NamedIndividual> 
</rdf:RDF> 

子要素が重複しないようにuuidを使用していますので、異なる<food>の場合は別の名前があります。出力testxqyoutput.rdfは有効なrdfファイルのように見えないかもしれませんが、私はソースコードの関連していない詳細をいくつか破棄しました。 実際の問題は、rdf:resourceに対応する名前を割り当てる方法がわかりません。

最初に生成NamedIndividualは次のようになります。

<owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#82ab6f48-2faf-4782-840f-59e6e96403ef_breakfast_menu"> 
    <rdf:type rdf:resource="#breakfast_menu"/> 
    <breakfast_menu_food rdf:resource="#04f02acc-da19-47a7-a69a-98cc958efbbd_food"/> 
    <breakfast_menu_food rdf:resource="#bfec0a13-ac56-4ac8-a9bb-0575b16e601a_food"/> 
    <breakfast_menu_food rdf:resource="#7f6411cb-3619-4b61-8b78-3b1e8ec99898_food"/> 
</owl:NamedIndividual> 
<owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#04f02acc-da19-47a7-a69a-98cc958efbbd_food"> 
     <rdf:type rdf:resource="#food"/> 
     <food_name rdf:resource=""/> 
     <food_price rdf:resource=""/> 
     <food_description rdf:resource=""/> 
     <food_calories rdf:resource=""/> 
     </owl:NamedIndividual> 
     <owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#bfec0a13-ac56-4ac8-a9bb-0575b16e601a_food"> 
     <rdf:type rdf:resource="#food"/> 
     <food_name rdf:resource=""/> 
     <food_price rdf:resource=""/> 
     <food_description rdf:resource=""/> 
     <food_calories rdf:resource=""/> 
     </owl:NamedIndividual> 
     <owl:NamedIndividual xmlns:owl="http://www.w3.org/2002/07/owl#" rdf:about="#7f6411cb-3619-4b61-8b78-3b1e8ec99898_food"> 
     <rdf:type rdf:resource="#food"/> 
     <food_name rdf:resource=""/> 
     <food_price rdf:resource=""/> 
     <food_description rdf:resource=""/> 
     <food_calories rdf:resource=""/> 
     </owl:NamedIndividual> 

どのように私は、この有効な出力を実現するためにコードを変更しますか? 本当の問題は、XQueryは関数型プログラミング言語だと思います。すべてのNamedIndividualsは関数によって生成されます。関数間で状態を共有する方法はありません。そして、XQueryにはglobal variableという概念はありません。

+1

uuidを要素コンストラクタの上の変数に格納し、それを単に2回使用するとどうなりますか?それはコンストラクタで直接生成するように見えますが、それはもちろん、それが複数回使用されるのを防ぎます。 –

+0

@HonzaHejzlあなたはもっと具体的になりますか?あらかじめ生成されたuuidをrdf:RDFのforループに入れるか、または関数forIndividualConstructorのforループに入れることを意味しますか?どうも –

答えて

0

これはうまくいくと思います。また、あなたのコード内のattribute rdf:resource {}が空であるため何もしません。

declare function local:namedIndividualConstructor($pnode as node()*) 
as node()* 
{ 
    (:to avoid repeated names, unique uuid is generated for each individuals:) 
    let $id := concat("#", random:uuid(), "_", $pnode/name()) 
    element owl:NamedIndividual 
    { 
    attribute rdf:about {$id}, 
    element rdf:type {attribute rdf:resource {concat("#", $pnode/name())}}, 

    for $x in $pnode/* 
    return element {local:getQName(concat($pnode/name(), "_", $x/name()))} 
    { 
     attribute rdf:resource {$id} 
    } 

    } 
};