XQuery: convert XML to RDF - xquery

I am trying to convert XML to RDF(RDF/XML syntax) using XQuery. I think I encounter something I could not overcome...
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>
command line:
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>
I use uuid to avoid duplicate child element, so for different <food>, there is a different name. The output testxqyoutput.rdf may not look like a valid rdf file, I discarded some not related details of the source code.
The real problem is: I don't know how to assign the corresponding name to rdf:resource.
The first generated NamedIndividual should look like this:
<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>
How do I modify the code to achieve this valid output?
I think the real problem is: XQuery is functional programming language. And all NamedIndividuals are generated by a function. There is no way to share status between functions. And there is no concept global variable in XQuery...

I would expect something like this could work. Besides, am I right the attribute rdf:resource {} in your code does nothing because it is empty?
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}
}
}
};

Related

datepicker, place the window to the right

I use Angular 13, Bootstrap 5 and ngx-bootstrap-fix-datepicker version 5 for my project.
"bootstrap": "^5.1.3",
"ngx-bootstrap": "^8.0.0",
"ngx-bootstrap-fix-datepicker": "^5.6.8",
My problem: I would like to place the calendar to the right and reduce the window.
Do you think it's possible? Because I have no idea.
datePicker - image
<div class="row row-cols-3 pt-3">
<div class="col text-end">
<label for="startDate" class="form-label">Date de départ</label>
</div>
<div class="col-4">
<input type="text " class="form-control form-max-width " name="startDate " [(ngModel)]="startDate " bsDatepicker [maxDate]="endDate " [required]="!!endDate " autocomplete="off ">
</div>
</div>
Update for angular:
You can add the placement property to your input tag like:
<input type="text " class="form-control form-max-width " name="startDate " [(ngModel)]="startDate " bsDatepicker [maxDate]="endDate " [required]="!!endDate " autocomplete="off " placement="right">
The other options you can use are "left | right | bottom | top"
Old answer:
You can all the following JavaScript to offset the top and left margin. Make sure to update the variable names to match your own.
$('input.date').datepicker({
beforeShow: function(input, inst) {
inst.dpDiv.css({
marginTop: -input.offsetHeight + 'px',
marginLeft: input.offsetWidth + 'px'
});
}
});

How do I style Labels with NativeScript Vue? Document example isn't working

I have a simple GridLayout
<GridLayout columns="*, *, *" rows="100">
<Label id="all-sales" text="0,0" row="0" col="0" style="background-color: blue"/>
<Label text="a,1" row="0" col="1" class="links" backgroundColor="blue" />
<Label text="0,1" row="0" col="3" class="links"/>
</GridLayout>
Note I have three labels that I am trying to style. The first uses an inline style, the second the what the NativeScript Docs call javascript property, and the last one with a class.
https://docs.nativescript.org/ui/styling
The only one that works is the javascript property.
This is an image of the iOS simulator.
I assuming I missing something because styling is in every example I've seen but it doesn't seem to work?
This is what I am running...
"dependencies": {
"#nativescript/theme": "^2.2.1",
"axios": "^0.19.2",
"nativescript-ui-listview": "^8.0.1",
"nativescript-ui-sidedrawer": "~8.0.0",
"nativescript-unit-test-runner": "^0.7.0",
"nativescript-vue": "~2.4.0",
"rxjs": "^6.4.0",
"tns-core-modules": "~6.3.0",
"typescript": "^3.7.5",
"vuex": "^3.1.2"
},

remove ID attribute from XML in Unix

I want to remove ID attribute from a XML file as below. Tries some sed command but it not yielding correct result. need help in correcting my sed command
<State>
<Resident Id="100">
<Name>Sample Name</Name>
<PhoneNumber>1234567891</PhoneNumber>
<EmailAddress>sample_name#example.com</EmailAddress>
<Address>
<StreetLine1>Street Line1</StreetLine1>
<City>City Name</City>
<StateCode>AE</StateCode>
<PostalCode>12345</PostalCode>
</Address>
</Resident>
<Resident Id="101">
<Name>Sample Name1</Name>
<PhoneNumber>1234567891</PhoneNumber>
<EmailAddress>sample_name1#example.com</EmailAddress>
<Address>
<StreetLine1>Current Address</StreetLine1>
<City>Los Angeles</City>
<StateCode>CA</StateCode>
<PostalCode>56666</PostalCode>
</Address>
</Resident>
<Resident Id="" />
</State>
Tried below sed commands but it not giving me correct result.
sed -i 's/^(ID=".*)".*/\1>/' Resident.xml
sed '/ ID.*/d' Resident.xml
Want xml like below. All id attributes removed from xml.
<State>
<Resident>
<Name>Sample Name</Name>
<PhoneNumber>1234567891</PhoneNumber>
<EmailAddress>sample_name#example.com</EmailAddress>
<Address>
<StreetLine1>Street Line1</StreetLine1>
<City>City Name</City>
<StateCode>AE</StateCode>
<PostalCode>12345</PostalCode>
</Address>
</Resident>
<Resident>
<Name>Sample Name1</Name>
<PhoneNumber>1234567891</PhoneNumber>
<EmailAddress>sample_name1#example.com</EmailAddress>
<Address>
<StreetLine1>Current Address</StreetLine1>
<City>Los Angeles</City>
<StateCode>CA</StateCode>
<PostalCode>56666</PostalCode>
</Address>
</Resident>
<Resident />
</State>
As other writes, you should not use sed, but if you have no other option.
sed 's/ Id=".*"//' file
<State>
<Resident>
<Name>Sample Name</Name>
<PhoneNumber>1234567891</PhoneNumber>
<EmailAddress>sample_name#example.com</EmailAddress>
<Address>
<StreetLine1>Street Line1</StreetLine1>
<City>City Name</City>
<StateCode>AE</StateCode>
<PostalCode>12345</PostalCode>
</Address>
</Resident>
<Resident>
<Name>Sample Name1</Name>
<PhoneNumber>1234567891</PhoneNumber>
<EmailAddress>sample_name1#example.com</EmailAddress>
<Address>
<StreetLine1>Current Address</StreetLine1>
<City>Los Angeles</City>
<StateCode>CA</StateCode>
<PostalCode>56666</PostalCode>
</Address>
</Resident>
<Resident />
</State>

md-select options doesn't work with md-menu?

I'm having an issue with md-options being hidden behind an md-menu - I'm using the md-select in a 'sub menu' (see image below):
It was asked about here and the answer was given that md-select was not supported inside of an md-menu yet, but I wonder if anyone has found a workaround? In my case, I have a dropdown of different checkboxes/selection options in each sub menu so using something like md-chips would really be a pivot from what I'm trying to accomplish.
HTML
<md-menu>
<md-button ng-click="$mdOpenMenu()">open menu</md-button>
<md-menu-content>
<md-menu-item>
<md-menu>
<md-button ng-click="$mdOpenMenu()">First ></md-button>
<md-menu-content>
<md-menu-item>
option 1
</md-menu-item>
<md-menu-item>
option 2
</md-menu-item>
<md-menu-item>
option 3
</md-menu-item>
</md-menu-content>
</md-menu>
</md-menu-item>
<md-menu-item>
<md-menu>
<md-button ng-click="$mdOpenMenu()">Second ></md-button>
<md-menu-content>
<md-input-container>
<md-select placeholder="Select an option..." ng-model="optionChosen">
<md-option ng-repeat="option in options" ng-value="option">
{{option}}
</md-option>
</md-select>
</md-input-container>
</md-menu-content>
</md-menu>
</md-menu-item>
</md-menu-content>
</md-menu>
JavaScript
app.controller('MainCtrl', function($scope) {
$scope.options = [
'option one',
'option two',
'options three'
];
$scope.optionChosen = null;
});
Working Code: Plunkr

Population data xquery

For the XML data below I am trying to get the output shown here: I.e I want to see the names of the countries having a population greater than 20000 , with the conditions that the number of cities displayed should only be for those with a population more than 3500. Also, For some countries the city is within a province.
<result>
<country name="B">
<num_cities>3</num_cities>
</country>
<country name="C">
<num_cities>2</num_cities>
</country>
</result>
---------------------------This is the XML data----------------------
<country id="1" name="A" population="12000">
<name>A</name>
<city id="c1" country="1">
<name>T1</name>
<population>5000</population>
</city>
<city id="c2" country="1">
<name>T2</name>
<population>3000</population>
</city>
<city id="c3" country="1">
<name>T3</name>
<population>4000</population>
</city>
</country>
<country id="3" name="B" population="80000">
<name>B</name>
<city id="c4" country="2">
<name>T4</name>
<population>6000</population>
</city>
<city id="c5" country="2">
<name>T5</name>
<population>2000</population>
</city>
<city id="c6" country="2">
<name>T6</name>
<population>60000</population>
</city>
<city id="c7" country="2">
<name>T7</name>
<population>12000</population>
</city>
</country>
<country id="3" name="C" population="68000">
<name>C</name>
<province>P1</province>
<city id="c8" country="3">
<name>T8</name>
<population>51000</population>
</city>
<city id="c9" country="3">
<name>T9</name>
<population>3000</population>
</city>
<city id="c10" country="3">
<name>T10</name>
<population>14000</population>
</city>
</country>
I wrote this xquery but i don't know how to exclude the cities having a population > 3500. I might not have written to code correctly either...Please assist.
for $c in doc("abc")//country
let $city:= count($c/city/name)
let $citypr:= count($c/province/city/name)
where $c/#population>1000000
return
<result>
<country name='{data($c/name) }'></country>
<num_of_cities>
{
if (exists ($c/city/name)) then
$city
else
$citypr
}
</num_of_cities>
</result>
Some hints:
Don't bother with where clauses where you can filter down earlier, in a specifier retrieving your content.
If you want to have only one <result>, rather than one per datum, you need to start it before the FLWOR expression; whatever you 'return' will be returned once per item.
This is an example of something closer:
<result>{
for $large-country in doc("abc")//country[#population > 20000]
let $large-cities := $country/city[population > 3500]
return
<country name="{$large-country/#name}">
<num_cities>{count($large-cities)}</num_cities>
</country>
}</result>

Resources