Using namespace in XPath query - xpath

I have the xml file which I made a XPath request for. But it works only without the xmlns-namespace. Can You help me with the adding correct namespace qualifier (I have errors)?
xml:
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<EventData>
<Data Name="ObjectServer">Security</Data>
<Data Name="ObjectType">File</Data>
<Data Name="ObjectName">C:\Temp\Project1.txt</Data>
</EventData>
</Event>
XPath:
*[EventData[Data[#Name="ObjectName" and (ends-with(text() ,".exe") or ends-with(text() ,".txt"))]]]
P.S. I'm using C++. My code based on this example from msdn. But I think its not significantly, because of I'm checking this request with online XPath tester.
Thanks.

Try this:
//*[local-name()='EventData' and ./*[local-name()='Data']
[#Name="ObjectName"and
(ends-with(text() ,".exe") or ends-with(text() ,".txt"))]]

Related

Replace element by XPath

I try to replace some element of my input XML in Citrus Framework.
My Spring context contains:
<citrus:namespace-context>
<citrus:namespace prefix="def" uri="http://sample.com/xmlns/2005"/>
</citrus:namespace-context>
My input file starts with:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<ns0:canonicalMessageHeader xmlns:ns0="http://sample.com/xmlns/2005">
<ns0:headerVersion>1.0</ns0:headerVersion>
<ns0:bodyVersion>1.0</ns0:bodyVersion>
<ns0:trackingInfo>
<ns0:eventHandlerInitInfo>
<ns0:processInfo>
<ns0:adapterTrackingId>214F27DF-E1FB-4E84-9122-390C5876ABD2:1</ns0:adapterTrackingId>
...
My endpoint is configured in that way:
<send endpoint="jms:topic:Order.Request?timeout=10000&connectionFactory=DEVconnectionFactoryFrom">
<message>
<resource file="com/sample/citrus/messages/input/SalesOrderTo.xml"/>
<element value="${track}" path="SOAP-ENV:Envelope/SOAP-ENV:Header/def:canonicalMessageHeader/def:trackingInfo/def:eventHandlerInitInfo/def:processInfo/def:adapterTrackingId"/>
I have the following error:
Can not evaluate xpath expression 'SOAP-ENV:Envelope/SOAP-ENV:Header/def:canonicalMessageHeader/def:trackingInfo/def:eventHandlerInitInfo/def:processInfo/def:adapterTrackingId'
at com/sample/citrus/SalesOrderToIT(sequential:45)
at com/sample/citrus/SalesOrderToIT(send:48-82)
Caused by: javax.xml.xpath.XPathExpressionException: org.apache.xpath.domapi.XPathStylesheetDOM3Exception: Prefix must resolve to a namespace: def
What's the possible cause of this error?
Best Regards
Global namespace declaration support is missing in Citrus when overwriting message elements in a send operation via XPath. This issue has been tracked: https://github.com/christophd/citrus/issues/331
In the meantime you have to use the exact same namespace prefix as in the message template file - in your case ns0:
Also you could throw away XPath overwrite and use the dot notated Node overwrite like this:
<send endpoint="jms:topic:Order.Request?timeout=10000&connectionFactory=DEVconnectionFactoryFrom">
<message>
<resource file="com/sample/citrus/messages/input/SalesOrderTo.xml"/>
<element value="${track}" path="Envelope.Header.canonicalMessageHeader.trackingInfo.eventHandlerInitInfo.processInfo.adapterTrackingId"/>
</message>
</send>
The dot notation is not based on namespaces but uses the local element names for finding the element in the message template. Obviously not as powerful as XPath but it works with current version of the framework.
You defined nso as namespace prefix in XML but then use def on the XPath, should be nso.

XSLTForms sort instance

I'm using XSLTforms on exist-db server and I'm trying to sort the instance. Here is an example of the model:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<xf:model>
<xf:instance xmlns="" id="default">
<data>
<x>
<a>B</a>
<a>C</a>
<a>A</a>
</x>
</data>
</xf:instance>
</xf:model>
</head>
Is it possible to sort somehow the elements in xf:repeat in order to get such a result:
A
B
C
I've tried using this examples, but unfortunately they don't work when I copy them in my project:
https://github.com/AlainCouthures/xsltforms/blob/master/testsuite/xforms-examples/03-output/sorting/sort.xhtml
https://github.com/AlainCouthures/xsltforms/blob/master/testsuite/xforms-examples/13-javascript/xslt-sort.xhtml
I'm new to xforms and I can't figure out why these examples don't work, so I would be very grateful if someone could give me a working example or point me to the right way to sort data in xsltforms.
Thank you in advance!
Unfortunately, there is nothing about sorting data in XForms specifications and these examples, using XSLT as a workaround, are actually not fully supported by XSLTForms at the JSON API level.
To run this with XSLTForms, you should replace:
instanceElement.parentNode.rebuild();
instanceElement.parentNode.recalculate();
instanceElement.parentNode.revalidate();
instanceElement.parentNode.refresh();
by:
XsltForms_globals.addChange(instanceElement.parentNode.id);
XsltForms_xmlevents.dispatch(instanceElement.parentNode, "xforms-rebuild");
XsltForms_globals.refresh();

Where can I obtain a sample RETS XML file?

I don't have an MLS login to retrieve a live RETS XML file, but I was wondering if someone could point me in the right direction to see a sample. Are there any "sandbox" MLS servers available for non-realtors to test RETS queries against?
I'm fine with it being filled with fake/stand-in data. Just trying to extrapolate how an actual data-file would look in relation to the DTD files made-available to developers before actually hooking any code up to a live MLS.
I haven't ever looked directly at the XML response returned from RETS since I use a library like librets that abstract that away for me so I can just process the data. I found an example of some data see reference document at the end for more info:
<RETS ReplyCode="0" ReplyText="">
<COUNT Records="2117">
<DELIMITER value="09"/>
<COLUMNS> ListingID ListPrice </COLUMNS>
<DATA> 12345678 300000 </DATA>
<DATA> 23456789 300000 </DATA>
<DATA> 34567890 300000 </DATA>
<DATA> 45678901 300000 </DATA>
<DATA> 56789012 310000 </DATA>
<DATA> 67890123 310000 </DATA>
<DATA> 78901234 310000 </DATA>
<DATA> 89012345 300000 </DATA>
<DATA> 90123456 350000 </DATA>
<DATA> 01234567 400000 </DATA>
</RETS>
[1] http://www.mredllc.com/%5Crets%5Cdocuments%5CRETS%20Developer%20Start%20Guide1.pdf
It's actually a violation of all MLS rules to provide any real estate data from their servers to a developer that hasn't been approved to build tools using their data. You'd need to become a vendor with the MLS and pay the associated fees to get access to the data.
Some MLSs provide the data to you for free to be a vendor, as long as you have an Agent or Broker that will sponsor you in that MLS. Other MLSs like Northstar in Minneapolis, MRIS / BrightMLS in the DC area charge as much as $1000 a year or more.
It's very important to get a license to use the data since it's copyright.

How to move property value from Properties file to payload object using spring integration elements

Sample.properties
=================
http.header.amisys.accept.value=arun/vnd.dsths.services-v1+xml
1)Above XSL automatically loaded when my server starts.
2)I have tried <int:enricher> element but it is not helped me.
Sample Code : Below is bit of code I have tried, Can any one suggest me on this.
<int:channel id="PQLegacySecurity-InputChannel" />
<int:chain input-channel="PQLegacySecurity-InputChannel" >
<!-- Split the Search Request Params from Xml -->
<int-xml:xpath-splitter>
<int-xml:xpath-expression expression="//LegacySecurity" namespace map="xmlMessageNamespace" />
</int-xml:xpath-splitter>
<int:enricher >
<int:payload name="testPayload" expression="${http.header.amisys.accept.value}"/>
</int:enricher>
</int:chain>
Actual Payload Object:Below is the xml which does not contain testPayload property.
<?xml version="1.0" encoding="UTF-8"?><LegacySecurity>
<businessArea>%%%%%%</businessArea>
<LegacySystem>%%%%%</LegacySystem>
<LegacyUserID>%%%%%</LegacyUserID>
<LegacyPassword>%%%%%</LegacyPassword>
<OtherLogin/>
<OtherPassword/>
<AddSecurLogin/>
<AddSecurPassword/>
</LegacySecurity>
Expected Payload Object: Below Object contains new element testPayload node which I should able to add
<?xml version="1.0" encoding="UTF-8"?><LegacySecurity>
<businessArea>%%%%%%</businessArea>
<LegacySystem>%%%%%</LegacySystem>
<LegacyUserID>%%%%%</LegacyUserID>
<LegacyPassword>%%%%%</LegacyPassword>
<OtherLogin/>
<OtherPassword/>
**<testPayload>arun/vnd.dsths.services-v1+xml</testPayload>**
<AddSecurLogin/>
<AddSecurPassword/>
</LegacySecurity>
You can use an xslt transformer. Something like the below, though you will need to figure out correct use of the transformer from the spring docs.
Notice you can pass a parameter through to the XSLT
<int-xml:xslt-transformer result-transformer="toDocumentTransformer" result-type="StringResult" xsl-resource="/xslt/addTestPayload.xslt">
<int-xml:xslt-param name="testPayload" value="${http.header.amisys.accept.value}"/>
</int-xml:xslt-transformer>
In the XSLT file, use this to pick up the parameter:
<xsl:param name="testPayload" />
If you have other changes you need to make to the message you can use the same xslt.

Using XPath functions in filter mediator

In my inSequence of a proxy I'm filtering with a xpath query in the filter mediator. But I want to use XPath functions like exists() or count(). But this does not work and always creates an exception. Here my example:
<filter xpath="count($body/myElement)>2">
<drop/>
</filter>
And the exception I always get:
ERROR - FilterMediator Error evaluating XPath expression : n:exists($body/avintis:Exception)
org.jaxen.UnresolvableException: No Such Function exists
How can I make these functions work?
You can use xpath functions with filter mediator as modifying your synapse segment as shown below.
<filter xpath="fn:exists($body/myElement)">
<drop/>
</filter>
You can refer for Sample 156: Service Integration with specifying the receiving sequence available at [1] for further sample.
<filter xpath="fn:number(get-property('SIMPLE_SER_AMT')) > fn:number(get-property('SECURE_SER_AMT'))">
[1]. http://wso2.org/project/esb/java/4.0.3/docs/samples/proxy_samples.html
Thank You,
Dharshana
For those wondering how to use fn:count, you could try:
<property name="itemCount" expression="fn:count(//*[local-name()='item'])"/>
<filter xpath="fn:number(get-property('itemCount')) > fn:number(0)">
This works for me.

Resources