Hello BaseX Staff,
I am trying to access members of a sequence that I have created already, but it whenever I use the functions subsequence() it returns the entire sequence, and count() always returns 1.
The code: xquery version "3.1"; declare namespace map="http://www.w3.org/2005/xpath-functions/map"; declare namespace xmi="http://www.omg.org/spec/XMI/20131001"; declare namespace uml="http://www.omg.org/spec/UML/20131001"; declare namespace MagicDraw_Profile=" http://www.omg.org/spec/UML/20131001/MagicDrawProfile"; declare namespace Extra_stereotypes=" http://www.magicdraw.com/schemas/Extra_stereotypes.xmi"; declare namespace UAF="http://www.omg.org/spec/UPDM/20121004/UPDM-Profile"; ( let $begin := db:open("CubeSatUML2.5XMIv3")/xmi:XMI/uml:Model/packagedElement let $modelContent := $begin//packagedElement[@xmi:type="uml:Class"] (: Combine the names of the elements with their ID's :) let $names := $modelContent/@name let $ids := $modelContent/@xmi:id (: Grab all stereotypes, properties:[attributes, comments] :) let $stereotypes := for $id in $ids let $stereo1 := /xmi:XMI/*[@base_Element=$id] let $stereo2 := /xmi:XMI/*[@base_Class=$id] let $attributes := $begin//*[@xmi:id=$id]/ownedAttribute/[@name | @xmi:type | @xmi:id] let $comments := $begin//*[@xmi:id=$id]/ownedComment/[@name | @xmi:type | @xmi:id | @body] let $combined := ($id, $stereo1/name(), $stereo2/name(), $comments, $attributes, "") return $combined
let $final := for $seq in $stereotypes return subsequence($seq, 1, 1) (: ^ the part in question:)
return $final )
I realize I am creating this in a very weird way, but I want to keep the data together and have not thought of another solution. I have tried 'for each'ing over the '$sequences' and tokenizing to get the elements out, but I get an error: let $finalMap := for $seq in $stereotypes return tokenize($seq, '\s') [XPTY0004] Item expected, sequence found: ("uml:Property", "_18_5_2_4c1014b_153850....
When I print '$stereotypes', I get what appears to be a sequence of sequences (which I don't think is a real thing, but it appears to be that)
Ex output:
xmi:id="_18_5_2_4c1014b_1538500371989_609286_80522" UAF:ResourceArtifact [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500468390_289646_80939", name="flight")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500488269_847951_81240", name="ground")]
xmi:id="_18_5_2_4c1014b_1538500376501_394659_80590" UAF:ResourceArtifact [(xmi:type="uml:Comment", xmi:id="_18_5_2_4c1014b_1538501028725_896600_82978", body="The ground supporting equipment and operations that support the spacecraft mission.")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500492755_533021_81326", name="ground Communications")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500495333_439654_81369", name="ground Command and Control")] [(xmi:type="uml:Port", xmi:id="_18_5_2_4c1014b_1538582001724_435913_83660", name="Flight_Ground")]
My end goal is to have a map of maps, where the root map has keys of element names (currently in $names) and the value is a map of all the properties of this element. To do this I have to deconstruct this monster I have created, and maybe I am on the wrong path entirely but some direction would be greatly appreciated.
End goal format:
map{ elementName : map { stereotypes: map{ stereotype_Name_1: stereotype_ID_1, stereotype_Name_2: stereotype_ID_2 }, attributeName: map{ 'id': actual_ID_here, 'lowerValue': someValue, 'upperValue': "*" }, comment: map{ 'id': actual_ID_here, 'xmi:type': 'uml:Comment', 'body': actual_Comment_Here }, 'id': actual_ID_here } }
Thanks,
Jordan Castillo </longWindedQuestion>
BaseX team,
Sorry for the long question but I just figured out what is going on...
The '$stereotypes' is a gigantic sequence, which is why I can't separate its members into sequences.
Hope you guys have a great week,
Jordan Castillo
On Tue, Jul 2, 2019 at 3:05 PM Jordan Castillo < jordantcastillo1992@gmail.com> wrote:
Hello BaseX Staff,
I am trying to access members of a sequence that I have created already, but it whenever I use the functions subsequence() it returns the entire sequence, and count() always returns 1.
The code: xquery version "3.1"; declare namespace map="http://www.w3.org/2005/xpath-functions/map"; declare namespace xmi="http://www.omg.org/spec/XMI/20131001"; declare namespace uml="http://www.omg.org/spec/UML/20131001"; declare namespace MagicDraw_Profile=" http://www.omg.org/spec/UML/20131001/MagicDrawProfile"; declare namespace Extra_stereotypes=" http://www.magicdraw.com/schemas/Extra_stereotypes.xmi"; declare namespace UAF="http://www.omg.org/spec/UPDM/20121004/UPDM-Profile "; ( let $begin := db:open("CubeSatUML2.5XMIv3")/xmi:XMI/uml:Model/packagedElement let $modelContent := $begin//packagedElement[@xmi:type="uml:Class"] (: Combine the names of the elements with their ID's :) let $names := $modelContent/@name let $ids := $modelContent/@xmi:id (: Grab all stereotypes, properties:[attributes, comments] :) let $stereotypes := for $id in $ids let $stereo1 := /xmi:XMI/*[@base_Element=$id] let $stereo2 := /xmi:XMI/*[@base_Class=$id] let $attributes := $begin//*[@xmi:id=$id]/ownedAttribute/[@name | @xmi:type | @xmi:id] let $comments := $begin//*[@xmi:id=$id]/ownedComment/[@name | @xmi:type | @xmi:id | @body] let $combined := ($id, $stereo1/name(), $stereo2/name(), $comments, $attributes, "") return $combined
let $final := for $seq in $stereotypes return subsequence($seq, 1, 1) (: ^ the part in question:)
return $final )
I realize I am creating this in a very weird way, but I want to keep the data together and have not thought of another solution. I have tried 'for each'ing over the '$sequences' and tokenizing to get the elements out, but I get an error: let $finalMap := for $seq in $stereotypes return tokenize($seq, '\s') [XPTY0004] Item expected, sequence found: ("uml:Property", "_18_5_2_4c1014b_153850....
When I print '$stereotypes', I get what appears to be a sequence of sequences (which I don't think is a real thing, but it appears to be that)
Ex output:
xmi:id="_18_5_2_4c1014b_1538500371989_609286_80522" UAF:ResourceArtifact [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500468390_289646_80939", name="flight")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500488269_847951_81240", name="ground")]
xmi:id="_18_5_2_4c1014b_1538500376501_394659_80590" UAF:ResourceArtifact [(xmi:type="uml:Comment", xmi:id="_18_5_2_4c1014b_1538501028725_896600_82978", body="The ground supporting equipment and operations that support the spacecraft mission.")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500492755_533021_81326", name="ground Communications")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500495333_439654_81369", name="ground Command and Control")] [(xmi:type="uml:Port", xmi:id="_18_5_2_4c1014b_1538582001724_435913_83660", name="Flight_Ground")]
My end goal is to have a map of maps, where the root map has keys of element names (currently in $names) and the value is a map of all the properties of this element. To do this I have to deconstruct this monster I have created, and maybe I am on the wrong path entirely but some direction would be greatly appreciated.
End goal format:
map{ elementName : map { stereotypes: map{ stereotype_Name_1: stereotype_ID_1, stereotype_Name_2: stereotype_ID_2 }, attributeName: map{ 'id': actual_ID_here, 'lowerValue': someValue, 'upperValue': "*" }, comment: map{ 'id': actual_ID_here, 'xmi:type': 'uml:Comment', 'body': actual_Comment_Here }, 'id': actual_ID_here } }
Thanks,
Jordan Castillo
</longWindedQuestion>
Hi Jordan,
Maybe the fn:head(), fn:tail(), and other functions for sequence operations would help[1]?
HTH! Best, Bridger
[1] https://www.w3.org/TR/xpath-functions-31/#sequence-functions
On Tue, Jul 2, 2019, 6:27 PM Jordan Castillo jordantcastillo1992@gmail.com wrote:
BaseX team,
Sorry for the long question but I just figured out what is going on...
The '$stereotypes' is a gigantic sequence, which is why I can't separate its members into sequences.
Hope you guys have a great week,
Jordan Castillo
On Tue, Jul 2, 2019 at 3:05 PM Jordan Castillo < jordantcastillo1992@gmail.com> wrote:
Hello BaseX Staff,
I am trying to access members of a sequence that I have created already, but it whenever I use the functions subsequence() it returns the entire sequence, and count() always returns 1.
The code: xquery version "3.1"; declare namespace map="http://www.w3.org/2005/xpath-functions/map"; declare namespace xmi="http://www.omg.org/spec/XMI/20131001"; declare namespace uml="http://www.omg.org/spec/UML/20131001"; declare namespace MagicDraw_Profile=" http://www.omg.org/spec/UML/20131001/MagicDrawProfile"; declare namespace Extra_stereotypes=" http://www.magicdraw.com/schemas/Extra_stereotypes.xmi"; declare namespace UAF="http://www.omg.org/spec/UPDM/20121004/UPDM-Profile "; ( let $begin := db:open("CubeSatUML2.5XMIv3")/xmi:XMI/uml:Model/packagedElement let $modelContent := $begin//packagedElement[@xmi:type="uml:Class"] (: Combine the names of the elements with their ID's :) let $names := $modelContent/@name let $ids := $modelContent/@xmi:id (: Grab all stereotypes, properties:[attributes, comments] :) let $stereotypes := for $id in $ids let $stereo1 := /xmi:XMI/*[@base_Element=$id] let $stereo2 := /xmi:XMI/*[@base_Class=$id] let $attributes := $begin//*[@xmi:id=$id]/ownedAttribute/[@name | @xmi:type | @xmi:id] let $comments := $begin//*[@xmi:id=$id]/ownedComment/[@name | @xmi:type | @xmi:id | @body] let $combined := ($id, $stereo1/name(), $stereo2/name(), $comments, $attributes, "") return $combined
let $final := for $seq in $stereotypes return subsequence($seq, 1, 1) (: ^ the part in question:)
return $final )
I realize I am creating this in a very weird way, but I want to keep the data together and have not thought of another solution. I have tried 'for each'ing over the '$sequences' and tokenizing to get the elements out, but I get an error: let $finalMap := for $seq in $stereotypes return tokenize($seq, '\s') [XPTY0004] Item expected, sequence found: ("uml:Property", "_18_5_2_4c1014b_153850....
When I print '$stereotypes', I get what appears to be a sequence of sequences (which I don't think is a real thing, but it appears to be that)
Ex output:
xmi:id="_18_5_2_4c1014b_1538500371989_609286_80522" UAF:ResourceArtifact [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500468390_289646_80939", name="flight")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500488269_847951_81240", name="ground")]
xmi:id="_18_5_2_4c1014b_1538500376501_394659_80590" UAF:ResourceArtifact [(xmi:type="uml:Comment", xmi:id="_18_5_2_4c1014b_1538501028725_896600_82978", body="The ground supporting equipment and operations that support the spacecraft mission.")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500492755_533021_81326", name="ground Communications")] [(xmi:type="uml:Property", xmi:id="_18_5_2_4c1014b_1538500495333_439654_81369", name="ground Command and Control")] [(xmi:type="uml:Port", xmi:id="_18_5_2_4c1014b_1538582001724_435913_83660", name="Flight_Ground")]
My end goal is to have a map of maps, where the root map has keys of element names (currently in $names) and the value is a map of all the properties of this element. To do this I have to deconstruct this monster I have created, and maybe I am on the wrong path entirely but some direction would be greatly appreciated.
End goal format:
map{ elementName : map { stereotypes: map{ stereotype_Name_1: stereotype_ID_1, stereotype_Name_2: stereotype_ID_2 }, attributeName: map{ 'id': actual_ID_here, 'lowerValue': someValue, 'upperValue': "*" }, comment: map{ 'id': actual_ID_here, 'xmi:type': 'uml:Comment', 'body': actual_Comment_Here }, 'id': actual_ID_here } }
Thanks,
Jordan Castillo
</longWindedQuestion>
Hi Jordan,
I’m glad to hear you solved the problem. Just a minor observation:
let $attributes := $begin//*[@xmi:id=$id]/ownedAttribute/[@name | @xmi:type | @xmi:id]
This query will create an XQuery array for each ownedAttribute element (with 3 attributes inside). You could additionally create an array for each stereotype item:
let $combined := [ $id, $stereo1/name(), $stereo2/name(), $comments, $attributes, "" ]
Later on, if you use subsequence(), head() or ...[1], you will get one single stereotype array item…
let $first := subsequence($stereotypes, 1) let $first := head($subsequence) (: equivalent :) let $first := $subsequence[1] (: equivalent :)
…and you can further process the array entries in the next step:
let $first-id := $first(1) (: access first array entry :) return $first-id
Maybe this helps you to build up the final map representation? The lookup operator (?) can be used for positional access. If $stereotype contains the array sequence (as generated above in my reply), it is very simple to retrieve the first member of all all arrays:
let $ids := $sterotypes?1
See [1,2] for more information on arrays and the lookup operator.
Cheers, Christian
[1] http://docs.basex.org/wiki/XQuery_3.1 [2] http://docs.basex.org/wiki/Array_Module
basex-talk@mailman.uni-konstanz.de