2016-05-05 6 views
2

Ich versuche, XML in RDF (RDF/XML-Syntax) mit XQuery zu konvertieren. Ich denke, dass ich etwas begegne ich nicht überwinden konnte ...XQuery: XML in RDF konvertieren

test.xqy:

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> 

Befehlszeile:

basex -o testxqyoutput.rdf test.xqy 

testxqyoutput. 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> 

Ich verwende uuid, um doppelte Kindelement zu vermeiden, so dass für verschiedene <food>, gibt es einen anderen Namen. Die Ausgabe testxqyoutput.rdf sieht möglicherweise nicht wie eine gültige rdf-Datei aus, ich habe einige nicht verwandte Details des Quellcodes verworfen. Das eigentliche Problem ist: Ich weiß nicht, wie man den entsprechenden Namen rdf:resource zuweist.

Die erste erzeugte NamedIndividual sollte wie folgt aussehen:

<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> 

Wie ändere ich den Code dieses gültige Ausgabe zu erreichen? Ich denke, das eigentliche Problem ist: XQuery ist funktionale Programmiersprache. Und alle NamedIndividuals werden von einer Funktion generiert. Es gibt keine Möglichkeit, den Status zwischen Funktionen zu teilen. Und es gibt kein Konzept global variable in XQuery ...

+1

Was ist mit dem Speichern der UUID in eine Variable über Element Konstruktoren und verwenden Sie es einfach zweimal? Es scheint, dass Sie es direkt im Konstruktor generieren, was natürlich verhindert, dass es mehr als einmal verwendet wird. –

+0

@HonzaHejzl Könnten Sie bitte spezifischer sein? Willst du die vorgenannte Uuid in die for-Schleife von rdf: RDF oder in die for-Schleife in Funktion namensIndividualConstructor? Danke –

Antwort

0

Ich würde erwarten, dass so etwas funktionieren könnte. Außerdem, habe ich recht die attribute rdf:resource {} in Ihrem Code tut nichts, weil es leer ist?

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} 
    } 

    } 
};