How to insert nodes after specific node of an instance in Orbeon? - orbeon

I have an instance in model:
<Exams>
<ExamCode>14</ExamCode>
</Exams>
<Exams>
<ExamCode>15</ExamCode>
</Exams>
I want to iterate on all elements and add after ExamCode element some nodes but without parent.
My instance after iterate should be like this:
<-- Wanted -->
<Exams>
<ExamCode>14</ExamCode>
<ExamTitle></ExamTitle>
<ExamDescription>/ExamDescription>
</Exams>
<Exams>
<ExamCode>15</ExamCode>
<ExamTitle></ExamTitle>
<ExamDescription></ExamDescription>
</Exams>
What i have tried is this:
Instance to add:
<!-- instance nodes to add-->
<xf:instance id="examRelatedNodes">
<ExamTitle/>
<ExamDescription/>
</xf:instance>
Adding "examRelatedNodes" instance to all repeated Exams nodes:
<!-- insert examRelatedNodes per Exam -->
<xf:action ev:event="xforms-ready" xxf:iterate="instance('fr-form-instance')/Exams">
<xf:insert context="." origin="instance('examRelatedNodes')"/>
</xf:action>
But I get an error that instance to add, should have parent!
I have read the documentation, this from the orbeon blog, but in all paradigms i find, the elements of to-add-instance have a parent, but in my case i don't want to have.Following these examples with parent node, i am able to add them, BUT with parent node "ParentOfExtraNodes" that i don't want:
<-- Not wanted -->
<Exams>
<ExamCode>14</ExamCode>
<ParentOfExtraNodes>
<ExamTitle></ExamTitle>
<ExamDescription>/ExamDescription>
<ParentOfExtraNodes/>
</Exams>
<Exams>
<ExamCode>15</ExamCode>
<ParentOfExtraNodes>
<ExamTitle></ExamTitle>
<ExamDescription>/ExamDescription>
<ParentOfExtraNodes/>
</Exams>
I am using Orbeon Forms 4.5 (XForms implementation).

What you are doing looks about right. But in your instance examRelatedNodes, you need to have a root element, say:
<xf:instance id="examRelatedNodes">
<RelatedNodes>
<ExamTitle/>
<ExamDescription/>
</RelatedNodes>
</xf:instance>
And then your insert will become:
<xf:insert context="." origin="instance('examRelatedNodes')/*"/>

Related

How to do an xforms:insert without the need of xforms:delete at the end?

<xf:action ev:event="xforms-model-construct">
<xf:insert nodeset="instance('subInstance')/type" origin="instance('defaultType')/type"/>
</xf:action>
I want to populate an instance based on another one. I can do this using xf:insert as shown above.
However, I realised that the instance 'subInstance' must contain an empty type element before starting the xf:inserts.
<subInstance>
<type/>
</subInstance>
So after all the xf:inserts, I need do the following to delete the first empty one:
<xf:delete nodeset="instance('subInstance')/type" at="1" />
Is there something wrong with this method or is there a way I can insert directly without an initial empty ?
Two answers:
You don't really need an initial type element
Your original instance can simply be:
<subInstance/>
And then you can insert into the subInstance element with:
<xf:action ev:event="xforms-model-construct">
<xf:insert
context="instance('subInstance')"
origin="instance('defaultType')/type""/>
</xf:action>
Using context without nodeset or ref says that you want to insert into the node pointed to by context.
You can still do what you want but with XForms 2.0 support
If you want to keep the original nested type element, you could write this:
<xf:action ev:event="xforms-model-construct">
<xf:insert
nodeset="instance('subInstance')"
origin="
xf:element(
'subInstance',
instance('defaultType')/type
)
"/>
</xf:action>
By targeting the root element of the destination instance, the entire instance will be replaced. This is already the case with XForms 1.1.
With the origin attribute's use of the xf:element() function from XForms 2.0, you can dynamically create an XML document rooted at subInstance and containing only the type elements from the defaultType instance.
To make this even more modern, you would replace nodeset with ref, as nodeset is deprecated in XForms 2.0:
<xf:action ev:event="xforms-model-construct">
<xf:insert
ref="instance('subInstance')"
origin="
xf:element(
'subInstance',
instance('defaultType')/type
)
"/>
</xf:action>

How to add variable number of values using swrl

This is my first post to stack overflow so I request for an encouraging reply :) (bonus reputations)
I am trying to use SWRL to do some calculations for me. To imitate the problem, I have created a small ontology using protege 4.3. It has only two classes Parent and Son. Instances include 1 parent (John) and three sons (son1, son2, son3). John is linked with 3 sons using "hasSon" object property. Age of each son is mentioned using "hasAge" data-type property (integers).
Question-1: I need to first check that how many instances are linked with a given Parent(John) using hasSon property. How this can be achieved in SWRL?
Question-2: After knowing the number of Sons then I have to add their ages to get the total age of all the Sons again using SWRL?
For me, this require a loop like addition (a=a+b) but I dont know how this will work in SWRL. I have attached the OWL code for you.
(Please note that in actual ontology the linked instances are not 3 but are varying and counting them is part of the problem)
Thanks in advance
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [
<!ENTITY owl "http://www.w3.org/2002/07/owl#" >
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
<!ENTITY parenttrial "http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#" >
]>
<rdf:RDF xmlns="http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#"
xml:base="http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:parenttrial="http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<owl:Ontology rdf:about="http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial"/>
<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Object Properties
//
///////////////////////////////////////////////////////////////////////////////////////
-->
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#hasSon -->
<owl:ObjectProperty rdf:about="&parenttrial;hasSon">
<rdfs:domain rdf:resource="&parenttrial;Parent"/>
<rdfs:range rdf:resource="&parenttrial;Son"/>
</owl:ObjectProperty>
<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Data properties
//
///////////////////////////////////////////////////////////////////////////////////////
-->
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#hasAge -->
<owl:DatatypeProperty rdf:about="&parenttrial;hasAge"/>
<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Classes
//
///////////////////////////////////////////////////////////////////////////////////////
-->
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#Parent -->
<owl:Class rdf:about="&parenttrial;Parent"/>
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#Son -->
<owl:Class rdf:about="&parenttrial;Son"/>
<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Individuals
//
///////////////////////////////////////////////////////////////////////////////////////
-->
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#JohnF -->
<owl:NamedIndividual rdf:about="&parenttrial;JohnF">
<rdf:type rdf:resource="&parenttrial;Parent"/>
<hasSon rdf:resource="&parenttrial;Son1"/>
<hasSon rdf:resource="&parenttrial;Son2"/>
<hasSon rdf:resource="&parenttrial;Son3"/>
</owl:NamedIndividual>
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#Son1 -->
<owl:NamedIndividual rdf:about="&parenttrial;Son1">
<rdf:type rdf:resource="&parenttrial;Son"/>
<hasAge rdf:datatype="&xsd;integer">3</hasAge>
</owl:NamedIndividual>
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#Son2 -->
<owl:NamedIndividual rdf:about="&parenttrial;Son2">
<rdf:type rdf:resource="&parenttrial;Son"/>
<hasAge rdf:datatype="&xsd;integer">4</hasAge>
</owl:NamedIndividual>
<!-- http://www.semanticweb.org/admin/ontologies/2015/7/parenttrial#Son3 -->
<owl:NamedIndividual rdf:about="&parenttrial;Son3">
<rdf:type rdf:resource="&parenttrial;Son"/>
<hasAge rdf:datatype="&xsd;integer">5</hasAge>
</owl:NamedIndividual>
</rdf:RDF>
<!-- Generated by the OWL API (version 3.4.2) http://owlapi.sourceforge.net -->
Answer 1: There is no way through SWRL to check how many instances are connected to a certain property through SWRL. You are better off writing a sparql query with COUNT for this. Alternatively you can use an ontology framework and use an Iteratorto figure out the counts.
Answer 2: There is no way to loop a SWRL rule, perform an operation and return a value. SWRL rules are meant to add extra information about relations and not act as a programming language.
Solution: You are far better off using a ontology framework like Apache Jena or Owl api and writing a program to handle this instead of relying on SWRL. SWRL supports monotonic inferences only and thus cannot be used to loop over data in an ontology. Trying to do so will cause the rule to get executed infinitely.
Instead write a bit of code to do this. Refer to owl api or Jena ontology api and sparql in order to learn more on how to use these technologies.

Custom XBL component for submitting form

I'm trying to implement a custom xbl component to submit the form to an external service, perform validation and handle the validation results. The version of orbeon is 4.4-CE deployed on JBoss 7.1.1.Final with MySQL persistence layer.
<xbl:binding element="fr|custom-submit" id="fr-custom-submit" xxbl:mode="lhha binding value">
<xbl:implementation>
<xf:model id="custom-submit-model">
<xf:instance id="validation-res">
<dummy/>
</xf:instance>
<!-- External validation submission -->
<xf:submission id="form-submission" ref="instance('fr-form-instance')"
action="http://localhost:8080/webapp/services/task/submitData" method="post"
replace="instance" instance="validation-res">
<xf:delete ev:event="xforms-submit" ref="//#v:*"/>
<xf:action ev:event="xforms-submit-done">
<!-- Insert external validation results when done -->
<xf:insert ref="." origin="instance('validation-res')/v:data/*"/>
<!-- Handle the valid/invalid result -->
</xf:action>
</xf:submission>
</xf:model>
</xbl:implementation>
<xbl:template>
<fr:button ref="xxf:binding('fr-custom-submit')">
<xf:label>
<xh:img src="/apps/fr/style/images/silk/disk.png"/>
<xh:span>Custom save</xh:span>
</xf:label>
<xf:send ev:event="DOMActivate" submission="form-submission"/>
</fr:button>
</xbl:template>
</xbl:binding>
Upon submitting the form the following exception occurs in the log files:
Empty single-node binding on xf:submission for submission id: form-submission |
I cannot figure out, what the exception means and if the cause of the problem is the strong encapsulation as described here.
Is it in general possible to write a custom xbl component for submitting a form? How can I overcome the above mentioned problem?
Regards
It is indeed an issue related to encapsulation, and using xxf:instance() allows you to break the encapsulation. So in your case, the submission would do:
ref="xxf:instance('fr-form-instance')"

Ant task to check that xml node exists in xml file

I have xml file inside that I want to add xml say
<car name="BMW">
<color>Red</color>
<model>x3</model>
</car>
I wish to check if node already exists then I want to update this otheriwse wanted to add new.
I am very new to ant xmltask so my question might be very simple.
With regards,
Avinash Nigam
using an additional root tag <foo></foo> for your example (needed for insert operation), with xmltask you may use =
<!-- edit file in place, use other dest if you need to create a new file -->
<xmltask source="path/to/file.xml" dest="path/to/file.xml">
<!-- create property if car node with name='BMW' exists -->
<copy path="//car[#name='BMW']/text()" property="modelexists"/>
<!-- insert new car node if car node with name='BMW' doesn't exist -->
<insert path="/foo" unless="modelexists">
<![CDATA[
<car name="BMW">
<color>Red</color>
<model>x3</model>
</car>
]]>
</insert>
<!-- replace car node if car node with name='BMW' exists -->
<replace path="//car[#name='BMW']" if="modelexists">
<![CDATA[
<car name="BMW">
<color>Blue</color>
<model>x4</model>
</car>
]]>
</replace>
</xmltask>

XStream fromXML with dynamic inner structure

I have XML object that I want converted back into the objects but am having trouble doing it with XStream. The problem with it is that the "RESULT" tag is different from different API services, so not sure how to alias it for different classes. The example below would be for a LOGIN service example. I may have another service that has the same Envelope/Body/RESULT/ but different attributes within it, i.e. Logout. Not sure how to go about leveraging the Envelope and Body to reduce redundent code.
<Envelope>
<Body>
<RESULT>
<SUCCESS>true</SUCCESS>
<SESSIONID>1320948a32098</SESSIONID>
<ORGANIZATION_ID>1</ORGANIZATION_ID>
</RESULT>
</Body>
</Envelope>
I have currently created classes for EnvelopeResponse, BodyResponse and a ResultResponse class I'll want all my other classes extending from? Is that the way to go about it? i.e. My LoginResponse class extends from ResultResponse.class, same for LogoutResponse.
I tried
xStream = new Xstream();
xStream.alias("Envelope", EnvelopeResponse.class);
xStream.alias("Body", BodyResponse.class);
xStream.alias("RESULT", LoginResponse.class); //Dynamic based on what API I'd like in the RESULT
Please help.
Since you are having multiple services, adding one more level of abstraction would be a good idea.
i.e.
<Envelope>
<Body>
<RESULT>
<LOGINRESPONSE>
<SUCCESS>true</SUCCESS>
<SESSIONID>1320948a32098</SESSIONID>
<ORGANIZATION_ID>1</ORGANIZATION_ID>
</LOGINRESPONSE>
</RESULT>
</Body>
</Envelope>
<Envelope>
<Body>
<RESULT>
<LOGOUT>
<SUCCESS>true</SUCCESS>
</LOGOUT>
</RESULT>
</Body>
</Envelope>
You can then alias these service responses to different classes,
xStream.alias("LOGOUT", LOGOUT.class);
xStream.alias("LOGINRESPONSE", LOGINRESPONSE.class);

Resources