XQuery Update Replace in Sedna - replace

I'm working on a little project for school. This project asks me to show that I'm capable of using various processing techniques of XML. Now, in my project I work with the Sedna database manager in which I keep user records and I would like to update some of these user records through XQuery (I use the PHP API to send the queries to the database through the PHP Api provided by the Sedna Developers team).
Imagine I have the following database content for the user records:
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="admin" admin="true">
<email>admin#admin.com</email>
<password>123456789</password>
<firstname>The</firstname>
<lastname>Stig</lastname>
<gender>male</gender>
<subscriptions>
</subscriptions>
</user>
<user id="prosper" admin="false">
<email>prosper#localhost.com</email>
<password>123456789</password>
<firstname>Strange</firstname>
<lastname>Figure</lastname>
<gender>male</gender>
<subscriptions>
</subscriptions>
</user>
</users>
Now, I my intention here is to update, for example, prosper's userrecord. In this record I would like to, for example, change his firstname and email, but keeping the rest unchanged.
I have tried to use the following query, but after sending the query, it changes the document order of the userrecord for some reason I don't understand (I think it inserts the attributes nodes of the user record as childnodes).
This is the query I use to update the user:
UPDATE replace $user in doc("users")//user[#id="prosper"]
with
<user>{($user/#*)}
<email>strange.figure#localhost.com</email>
{($user/node()[password])}
<firstname>Familiar</firstname>
<lastname>Figure</lastname>
<gender>male</gender>
{($user/node()[subscriptions])}</user>
Now, the problem this query gives me, is that when I try to ask the user's information after the update, I rely on the same order of child nodes have from before the update, but this query changes the order.
Is there someone skilled enough to help me with this problem?
I thank you for your time.

Jan, if you want to get password node you should change your XPath (your current expression {($user/node()[password])} is not what you think):
{$user/password}
the same true for subscriptions:
{$user/subscriptions}
It can be written as one expression with predicate:
{$user/node()[local-name(.) = ('password', 'subscriptions')]}

Related

Addressing an xml value in enrich Mediator

I want to address an xml value in the Xpath field within the enrich mediator in order to customize an API response. My xml input is as follow:
<member>
<name>ABC</name>
</value>1</value>
</member>
I tried to access the 'ABC' value by using this code:
$body//member[#name='ABC']
but it does not work for me.
First of all your XML input is not valid. There is no opening value tag but two closing.
Can you try //member/name/text(),this worked für me.If its not working,then maybe you need to add the namespaces.
Hope that helps.

Twilio + Django - Voice message

Here's my requirement:
I have a text ="Thank you for your response". I want to initiate a call with a user, and when the user picks up the call, i want the text message to be turned into a voice message.
Here's what i have so far:
I am initiating a twilio call:
twilioClient.calls.create(to=user_number, from_=twilio_number, \
url="https://testserver.com/call/")
In urls.py, i have /call/ that points to my django view module
In view, the module looks like:
def testTwilioCall(request):
return HttpResponse(open('/path/call.xml').read(), content_type='application/xml')
-call.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say voice="woman">Thank you for your response.</Say>
<Record maxLength="20" />
</Response>
Here's whats happening:
User gets a call, and the call says - "Sorry application error".
I am not sure what is going wrong. When i replace the url parameter with https://demo.twilio.com/welcome/voice/, it works.
I also double checked that the xml is being displayed fine from the browser.
Not sure where i am going wrong with rendering the xml.
PS: testserver is just a placeholder.

Over-riding DRI Templates using xsl in DSpace

I'm working with DSpace 4.2 xmlui Mirage theme. I want to hide the Communities and Collections from the search results page.
By inspecting the DRI document of the page I found that the Communities and Collections results are added as:
<list id="aspect.discovery.SimpleSearch.list.comm-coll-result-list" n="comm-coll-result-list">
So I tried over-riding the template in the xsl file of the theme.
<xsl:template match="dri:list[#id='aspect.discovery.SimpleSearch.list.comm-coll-result-list']">
<!-- Over ride / remove the recent submissions box-->
</xsl:template>
But no change is reflected in the page. Am I doing something wrong here? I was able to hide the default search box in a similar manner by over-riding the template generating it's corresponding div.I noticed that the list item I want to hide is contained within another div. Is is not possible to over-ride a DRI element unless its tag is div?
You can also add a default filter query in your [dspace]/config/spring/api/discovery.xml.
Default filter queries are applied on all search operations & sidebarfacet clicks. One useful application of default filter queries is ensuring that all returned results are items. As a result, subcommunities and collections that are returned as results of the search operation, are filtered out.
Relevant lines here, note that this is disabled by default. Uncomment to make this work.
<property name="defaultFilterQueries">
<list>
<value>search.resourcetype:2</value>
</list>
Hope this help.
UPDATE
Copy the:
<property name="defaultFilterQueries">
<list>
<value>search.resourcetype:2</value>
</list>
<property>
in the <bean id="homepageConfiguration" class="org.dspace.discovery.configuration.DiscoveryConfiguration" scope="prototype"> because it overrides the defaultConfiguration as stated in this comment.
The collection and community list results are displayed by the following XSLT: https://github.com/DSpace/DSpace/blob/master/dspace-xmlui/src/main/webapp/themes/dri2xhtml/structural.xsl#L3616-L3635
To change the display via XSLT, try constructing your own template code.
<xsl:template name="collectionSummaryList">
<xsl:param name="handle"/>
<xsl:param name="externalMetadataUrl"/>
<xsl:variable name="metsDoc" select="document($externalMetadataUrl)"/>
...
</xsl:template>
If you completely suppress these results from your display, it will likely make your pagination counts unreliable. It might make more sense to suppress the community/collection results from the SOLR search results.

Getting and displaying data from database with xforms on submission

I have a database with an xml document in it, and I want to display a transformed xml on my xforms page, when the submission is sent (I'm using orbeon forms).
My solution is, that on the submission my servlet gets the xml from the database, writes it into a file, xslt transforms the xml tree (when and how should I do the transformation?), but I don't know, how to display this file on the xforms page. Maybe the replace="instance" attribute in can help, but i don't know how.
Thanks!
Now, after Alessandro's advice, Im trying to use this xpl thing, but it doesn't work.
In the model:
<xforms:insert nodeset="instance('inst2')"
origin="xxforms:call-xpl('oxf:/resources/pipeline.xpl', 'data',
instance('inst1'), 'data')"/>
in pipeline.xpl:
<p:config xmlns:p="http://www.orbeon.com/oxf/pipeline"
xmlns:oxf="http://www.orbeon.com/oxf/processors">
<p:param type="input" name="data"/>
<p:param type="output" name="data"/>
<p:processor name="oxf:xslt">
<p:input name="data" href="#data"/>
<p:input name="config" href="transform.xsl"/>
<p:output name="data" ref="data"/>
</p:processor>
My instance, that I want to transform is "complaint-instance", the transformed instance called "trf-instance", the pipeline.xpl file is in the same directory with my xforms page. My styesheet called customerToOperator.xsl. What's wrong in my code?
I just noticed, the note: "If you are using separate deployment, the service and XSLT transformation must be present in the Orbeon WAR file, instead of within your application."
Ehm... Where should I put these files?
my app in details:
a) an xforms page, with 2 instances:
<instance id='inst1'>
<name>
<lastname/>
<firstname/>
</name>
</instance>
<instance id='inst2'>
<fname>
<fullname/>
</fname>
</instance>
I got 2 input fields, referenced on name/lastname and name/firstname.
I have an xforms:insert node, described above, and an xforms:submission node:
<xforms:submission
id="save-submission"
ref="instance('inst2')"
action="/my-servlet"
method="post"
replace="none">
I added 2 files to orbeon/WEB-INF/resources, the pipeline.xpl, (described above) and transform.xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<fname>
<fullname>
<xsl:value-of select="name/firstname"/>
<xsl:value-of select="name/lastname"/>
</fullname>
</fname>
</xsl:template>
</xsl:stylesheet>
And I have a servlet, which writes the posted instance on the console (now it writes inst2 on the console, but without the user input data, only the nodes...)
A really need to fix this...
Thanks again!
To get the XML from a database (relational or not) and apply a transformation, instead of writing my own servlet, I would use an XPL pipeline, and map this pipeline to a URL through the page flow. Now you have a service that answers to an HTTP request and returns XML. To call the service from XForms, you use an <xforms:submission replace="instance">. You end up with the XML in an instance, and you can display it with something like: <xforms:output value="saxon:serialize(instance(), 'xml')"/>.
In all cases (including separate deployment), the pipeline and XSLT file must be in the "resources". Usually, this means the WEB-INF/resources of the Orbeon's web app. But you can also do more fancy things by setting up the Orbeon resource manager to also use other directories on disk.

Is it possible to search SharePoint metadata?

When I use the Search.asmx web service it won't allow me to search MetaData. Is there a way that I can do this?
Below is what I have come up with so far for my query, but it errors out with an InvalidPropertyException every time I run it.
<?xml version="1.0" encoding="utf-8" ?>
<QueryPacket xmlns="urn:Microsoft.Search.Query" Revision="1000">
<Query domain="QDomain">
<SupportedFormats><Format>urn:Microsoft.Search.Response.Document.Document</Format></SupportedFormats>
<Context>
<QueryText language="en-US" type="MSSQLFT">
<![CDATA[ SELECT Title, Rank, Size, Description, Write, Path FROM portal..scope() WHERE "Published" = 'Yes' ORDER BY "Rank" DESC ]]>
</QueryText>
</Context>
<Range><StartAt>1</StartAt><Count>20</Count></Range>
<EnableStemming>false</EnableStemming>
<TrimDuplicates>true</TrimDuplicates>
<IgnoreAllNoiseQuery>true</IgnoreAllNoiseQuery>
<ImplicitAndBehavior>true</ImplicitAndBehavior>
<IncludeRelevanceResults>true</IncludeRelevanceResults>
<IncludeSpecialTermResults>true</IncludeSpecialTermResults>
<IncludeHighConfidenceResults>true</IncludeHighConfidenceResults>
</Query></QueryPacket>
You can't just search an arbitrary column of metadata, you need to make sure it gets crawled first and is made available under a sensible name (managed property). See this blog post for an example.
Also, if Published is a boolean, I think you might want to test "Published" = 1, in stead of yes.