Correct Xpath - - xpath

I have a xml like -
<?xml version="1.0" encoding="UTF-8"?>
<oslc_cm:Collection xmlns:oslc_cm="http://open-services.net/xmlns/cm/1.0/"
oslc_cm:totalCount="7"
xmlns:dc="http://purl.org/dc/terms/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rtc_cm="http://jazz.net/xmlns/prod/jazz/rtc/cm/1.0/">
<rtc_cm:Action rdf:resource="https://rtc.gsissc.myatos.net:9443/ccm/oslc/workflows/_ezLt4PJ7EeGRg6GNKwqw9g/actions/com.ibm.team.workitem.defectWorkflow/com.ibm.team.workitem.defectWorkflow.action.resolve">
<dc:identifier>com.ibm.team.workitem.defectWorkflow.action.resolve</dc:identifier>
<rtc_cm:resultState rdf:resource="https://rtc.gsissc.myatos.net:9443/ccm/oslc/workflows/_ezLt4PJ7EeGRg6GNKwqw9g/states/com.ibm.team.workitem.defectWorkflow/3"/>
<dc:title>Resolve</dc:title>
<rtc_cm:iconUrl>https://rtc.gsissc.myatos.net:9443/ccm/service/com.ibm.team.workitem.common.internal.model.IImageContentService/processattachment/_ezLt4PJ7EeGRg6GNKwqw9g/workflow/resolve.gif</rtc_cm:iconUrl>
</rtc_cm:Action>
From it I have to fetch rtc_cm:resultState rdf:resource.
What would be the correct XPath for it. I am using XPathExpression xPathExpressionDescription = xpath.compile("../rtc_cm:resultState/#rdf:resource"); which is giving me null pointer.
Please guide me .

../rtc_cm:resultState/#rdf:resource
That's assuming the context node – the node to which your XPath expression is relative – is a sibling of rtc_cm:resultState.
You might be better with an absolute path, based on the document root. Something like:
/oslc_cm:Collection/rtc_cm:Action/rtc_cm:resultState/#rdf:resource
(and, of course, assuming you are passing an implementation of IXmlNamespaceResolver set up with all the applicable namespaces).

The absolute path would be:
/oslc_cm:Collection/rtc_cm:Action/rtc_cm:resultState/#rdf:resource
If you know there is only one instance of resultState or if you want to query for all instances:
//rtc_cm:resultState/#rdf:resource
Please make sure that your namespace manager has definitions for the namespaces you use in your XPath expression.

Related

getting first node of xml in logicapps

I need to have first node of below xml that is inside of FIToFICstmrCdtTrf. However, xpath returns binary data.
xpath(xml(triggerBody()),'/')
xpath(xml(triggerBody())x,'/FIToFICstmrCdtTrf')
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>x</MsgId>
<CreDtTm>x</CreDtTm>
<NbOfTxs>2</NbOfTxs>
....
Your XML is bound to the namespace urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02, so unless you register the namespace in order to be able to use a namespace-prefix in your XPath, you need to address the elements by their local-name().
For instance: /*[local-name()="Document"]/*[local-name()="FIToFICstmrCdtTrf"]
and then to select the first child element (GrpHdr), you can append a generic expression selecting any element * and apply a predicate filter to select the first: /*[1]
Putting it all together:
xpath(xml(triggerBody()),
'/*[local-name()="Document"]/*[local-name()="FIToFICstmrCdtTrf"]/*[1]')
After reproducing from my end, I was able to get this working by applying the below expressions in the flow of my logic app:
xpath(xml(variables('XML')),'/*[local-name()="Document"]/*[local-name()="FIToFICstmrCdtTrf"]/*')?[0]
OR
xpath(xml(variables('XML')),'/*[name()="Document"]/*[name()="FIToFICstmrCdtTrf"]/*')?[0]
Below is the flow of my logic app
RESULTS:

Access deep nested node from document.xml using nokogiri

I am using nokogiri to access a docx's document xml file.
here is a sample of it:
<w:document>
<w:body>
<w:p w:rsidR="00454EDC" w:rsidRDefault="00454EDC" w:rsidP="00454EDC">
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="1926590" cy="1088571"/>
<wp:effectExtent l="0" t="0" r="0" b="0"/>
<wp:docPr id="1" name="Picture 1"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="Picture 1"/>
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId5" cstate="print">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="1951299" cy="1102532"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln>
<a:noFill/>
</a:ln>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:p>
</w:body>
</w:document>
Now I want to access all <w:drawing> tags and from them I wan to access <a:blip> tag and extract the value of attribute of r:embed from it.
In this case as you can see it is rId5
I am able to access the <w:drawing> tag by using xml.xpath('//w:drawing') but when I do so xml.xpath('//w:drawing').xpath('//a:blip'), it throws error :
Nokogiri::XML::XPath::SyntaxError: Undefined namespace prefix: //a:blip
What am I doing wrong, can anyone point me in the right direction?
The error is telling you that in your XPath query, //a:blip, Nokogiri doesn’t know what namespace a refers to. You need to specify the namespaces that you are targeting in your query, not just the prefix. The fact that the prefix a is defined in the document doesn’t really matter, it is the actual namespace URI that is important. It is possible to use completely different prefixes in the query than those used in the document, as long as the namespace URIs match.
You may be wondering why the query //w:drawing works. You don’t include the full XML, but I suspect that the w prefix is defined on the root node (something like xmlns:w="http://some.uri.here"). If you don’t specify any namespaces, Nokogiri will automatically register any defined in the root node so they will be available in your query. The namespace corresponding to the a prefix isn’t defined on the root, so it is unavailable, and so you get the error you see.
To specify namespaces in Nokogiri you pass a hash, mapping the prefix (as used in the query) to namespace URI, to the xpath method (or which ever query method you’re using). Since you are providing your own namespace mappings, you also need to include any you use from the root node, Nokogiri doesn’t include them in this case.
In your case, the code would look something like this:
namespaces = {
'w' => 'http://some.uri', # whatever the URI is for this namespace
'a' => 'http://schemas.openxmlformats.org/drawingml/2006/main'
}
# You can combine this to a single query.
# Also note you don’t want a double slash infront of
# the `/a:blip` part, just one.
xml.xpath('//w:drawing/a:blip', namespaces)
Have a look at the Nokogiri tutorial section on namespaces for more info.
I would say that this is a bug in the xml parser that you are using :
Indeed, the error seems to be that the namespace prefix a is undefined, however, it has been defined in <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">, which is a parent of the <a:blip> element.
See here if you want to know more about xml namespaces
It seems that they are a few other questions about problems with namespace prefixes in nokogiri, for example : Undefined namespace prefix in Nokogiri and XPath

XPath format required on namespace node

Can someone please show me the XPath format i should use to retrieve the 2nd txnDetail node's billAmount ?
I am expecting value 10.00 but i have issues with the namespace and "a:" and XPath fails to retrieve the correct value.
<TransactionRsp xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<avlBal>818.00</avlBal>
<blkAmt>0.00</blkAmt>
<cardID>2561683577196298</cardID>
<currBill>GBP</currBill>
<endBal>390.00</endBal>
<logDateTime>2013-04-30T12:17:20.4249292Z</logDateTime>
<msgID>121719721</msgID>
<rspCode>000</rspCode>
<startBal>400.00</startBal>
<txnDetail xmlns:a="http://schemas.datacontract.org/2004/07/CoreModels">
<a:txnDetail>
<a:billAmount>400.00</a:billAmount>
<a:billConvRate>0.00</a:billConvRate>
<a:blkAmount>0.00</a:blkAmount>
<a:debOrCred>1</a:debOrCred>
<a:itemID>2278</a:itemID>
<a:itemType>6</a:itemType>
<a:txnAmount>0.00</a:txnAmount>
<a:txnCurrency/>
<a:txnDateTime>2012-02-23T14:35:45</a:txnDateTime>
<a:txnDescription></a:txnDescription>
</a:txnDetail>
<a:txnDetail>
<a:billAmount>10.00</a:billAmount>
<a:billConvRate>0.00</a:billConvRate>
<a:blkAmount>0.00</a:blkAmount>
<a:debOrCred>0</a:debOrCred>
<a:itemID>3058</a:itemID>
<a:itemType>5</a:itemType>
<a:txnAmount>0.00</a:txnAmount>
<a:txnCurrency/>
<a:txnDateTime>2012-07-30T12:22:14</a:txnDateTime>
<a:txnDescription>Fee: Card Issue</a:txnDescription>
</a:txnDetail>
</txnDetail>
</TransactionRsp>
It's:
//TransactionRsp/txnDetail/a:txnDetail[2]
However, depending on your programming language you might have to register the a namespace. The document might have a default namespace as well. (Don't expect that the xml you've posted is the whole document)
I have managed to pull the relevant data using the following XPath:
/TransactionRsp/txnDetail/[local-name()='txnDetail'][2]/[local-name()='billAmount']
Now I need to know how to filter out only txnDetail with an itemType = 6 ??
Any thoughts ?

How to Use Query_Match for Soap UI

I am having trouble using the MockOperation Editor in Soap UI.
I have got this request:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<methodName xmlns="http://tempuri.org/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<dataAreaId>error</dataAreaId>
<pInvoiceList>
<dataAreaId>NOTTHESAME</dataAreaId>
...
</pInvoiceList>
</methodName>
</s:Body>
</s:Envelope>
I tried almost every XPATH expression but I always get "Missing match in request"
What to fill in the Xpath box?
I tried:
//dataAreaId/text()
//dataAreaId/
//dataAreaId
/dataAreaId/text()
/dataAreaId
/methodName/dataAreaId/text()
/methodName/dataAreaId/
/methodName/dataAreaId
I finally managed to get it based on the answer from user1740631
Seems I it had to do with namespaces afterall.
The correct syntax:
declare namespace tem='http://tempuri.org/';
//tem:methodName/tem:dataAreaId[1]
If you don't care about namespaces you can use the following syntax:
XPath1.0
//*[local-name() = 'methodName']/*[local-name() = 'dataAreaId'][1]
XPath2.0
//*:methodName/*:dataAreaId[1]
Write like this
For First One
//methodName[1]/dataAreaId[1]
For Second one
//methodName[1]/pInvoiceList[1]/dataAreaId[1]
*If you have multiple node with same name in Xml then you should use numbers to locate that particular node.
There is a good hint: When defining an Assertion for a Testcase (or maybe also in the Mock-Window) there is a button "Declare" above the XPath-Expression-Field. It doesn't really look like a button, until you point with the mouse-pointer at it, so I didn't realize it at first.
Just click on the button an SoapUI (actually I use 5.2.1) will add the declare-statements for you, that you can use.
I found that feature coincidentally, as it is not really visible. Maybe this can help also...

XPath using string functions in the middle of the path

I'm trying to use Web Deploy 3.0 to make changes to my web.config before deployment. Let's say I have the following xml:
<node>
<subnode>
<connectInfo httpURL="http://LookImAUrl.com" />
</subnode>
<node>
And I'd like to match just the "http" in "http://..." so that I can potentially replace it with https.
I looked into XPath string functions and understand them -- I just don't know how to put them in the middle of an expression, for example:
"//node/subnode/connectInfo/#httpURL/substring-before(../#httpURL,':')"
That's basically what I want to do, but it doesn't look right.
"//node/subnode/connectInfo/#httpURL/substring-before(../#httpURL,':')"
That's basically what I want to do, but it doesn't look right.
But it is right and will match the http.
(Btw, you could write it shorter without ..
//node/subnode/connectInfo/#httpURL/substring-before(.,':')
)
However, it will return the string "http" not some kind of pointer pointing to the value of #httpUrl, which is not possible, since there are no partial nodes within the value.
(In XPath 2,) you can return the attribute and a new value, and then perhaps change it in the calling language
//node/subnode/connectInfo/#httpURL/(., concat("https:", substring-after(.,':')))
Using XPath 1.0, if you want to return the initial part of the URL use:
substring-before(//node/subnode/connectInfo/#httpURL,':')
Note though that this will return the value of ONLY the first connectInfo element.
If you want to get the connectInfo nodes that use HTTP:
//node/subnode/connectInfo[starts-with(#httpURL,'http:')]
If you wan to get all httpURL that use HTTP:
//node/subnode/connectInfo/#httpURL[starts-with(.,'http:')]

Resources