I am not able to get xpath value "MatchFound" for the below xml in soapui .
I am trying property transfer functionality .
I tried following XPath :
declare namespace ns0='http://KYC/';
declare namespace soapenv='http://schemas.xmlsoap.org/soap/envelope/';
/soapenv:Envelope/soapenv:Body/BarclaysCustomerValidationResponse/oCasaDetailByRefNoDetails/oCasaStatusByRefNoDetails/oRiskProfileClientData/oGetFraudInformationData/oAddressVerificationDetails/ns0:matchedFound
XML :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<BarclsCustomerValidationResponse xmlns="http://BHKYC/BarclaysCustomerValidation.tws">
<oCasaByIdNoDetails>
<ns0:casaByIdNoResults xmlns:ns0="http://KYC">
<ns0:item/>
</ns0:casaByIdNoResults>
</oCasaByIdNoDetails>
<oCasaDetailByRefNoDetails/>
<oCasaStatusByRefNoDetails/>
<oRiskProfileClientData/>
<oGetFraudInformationData/>
<oAddressVerificationDetails>
<ns0:enquiryid xmlns:ns0="http://KYC">51644325</ns0:enquiryid>
<ns0:enquiryresultid xmlns:ns0="http://KYC">52146422</ns0:enquiryresultid>
<ns0:matchedFound xmlns:ns0="http://KYC">false</ns0:matchedFound>
<ns0:numberOfMatches xmlns:ns0="http://KYC">1</ns0:numberOfMatches>
<ns0:firstMatchUpdatedDate xmlns:ns0="http://KYC">2016-03-31</ns0:firstMatchUpdatedDate>
<ns0:secondMatchUpdatedDate xmlns:ns0="http://KYC"/>
<ns0:mostRecentAddressIsMatched xmlns:ns0="http://KYC">false</ns0:mostRecentAddressIsMatched>
</oAddressVerificationDetails>
<oCasaPS/>
<pid>21691</pid>
</BarclsCustomerValidationResponse>
</soapenv:Body>
</soapenv:Envelope>
Here are some of the problems :
namespace URI assigned to ns0 in the XPath/XQuery doesn't match the one in the XML
the XML has default namespace declared at BarclsCustomerValidationResponse element. This means BarclsCustomerValidationResponse and all the descendant elements without prefix are in the same namespace. You need to declare another prefix, map it to the default namespace URI, and use the prefix accordingly in the XPath
The following works for me :
declare namespace ns0='http://KYC';
declare namespace d='http://BHKYC/BarclaysCustomerValidation.tws';
declare namespace soapenv='http://schemas.xmlsoap.org/soap/envelope/';
/soapenv:Envelope
/soapenv:Body
/d:BarclsCustomerValidationResponse
/d:oAddressVerificationDetails
/ns0:matchedFound
Demo: http://www.xpathtester.com/xquery/b8f1f1e9e0c64af37a2e398d5b911569
BarclaysCustomerValidationResponse is in namespace http://BHKYC/BarclaysCustomerValidation.tws, so your XPath expression /BarclaysCustomerValidationResponse/ cannot find it. Same goes for its child elements unless they have a particular namespace prefix like ns0:.
Just for reading XML in SoapUI, you do not need to bother with namespaces. As you have discovered, they make the XPath unnecessarily complicated. For your case, something as simple as this will suffice.
//*:matchedFound
Related
Im trying to learn to parse xml with nokogiri.
I dont have control of how the xml file is generated and it seems the namespaces are causing issues because they are not defined.
Im using the following test code to try to get this to work.
require 'nokogiri'
def getxml
xml_str = <<EOF
<root>
<THING1:things type="Container">
<PART1:Id type="Property">1234</PART1:Id>
<PART1:Name type="Property">The Name1</PART1:Name>
</THING1:things>
<THING2:things type="Container">
<PART2:Id type="Property">2234</PART2:Id>
<PART2:Name type="Property">The Name2</PART2:Name>
</THING2:things>
</root>
EOF
doc = Nokogiri::XML(xml_str)
puts(doc.errors())
doc.xpath('//Id').each do |thing|
puts(thing.inspect)
#puts "ID = " + thing.at_xpath('Id').content
#puts "Name = " + thing.at_xpath('Name').content
end
end
getxml()
I'm getting the following errors:
2:38: ERROR: Namespace prefix THING1 on things is not defined
3:34: ERROR: Namespace prefix PART1 on Id is not defined
4:36: ERROR: Namespace prefix PART1 on Name is not defined
6:38: ERROR: Namespace prefix THING2 on things is not defined
7:34: ERROR: Namespace prefix PART2 on Id is not defined
8:36: ERROR: Namespace prefix PART2 on Name is not defined
How am I suppose to deal with namespaces not defined. Is there a way to ignore namespaces.
Nokogiri does have the remove_namespaces! method, but it wont help in your case as your XML isn’t actually using namespaces.
As there are no namespace declarations, your XML elements are just treated as non-namespaced elements that contain a : character in their name. This makes it difficult to use with XPath as XPath assumes a : indicates a namespace.
One way to get round this is to use the local-name() function to select elements. For example to select all elements named PART1:Id you could use this:
doc.xpath('//*[local-name()="PART1:Id"]')
If you want to select all elements where the final part is Id, regardless of what the prefix is, such as PART1:Id and PART2:Id, you could combine local-name() with substring-after():
doc.xpath('//*[substring-after(local-name(), ":")="Id"]')
<payload xsi:type="ns787:SomeRequest" xmlns:ns787="http://ws.abc.efg.com"/>
I'm working with IIB v10.0.0.7. I'd like to define one of the XML elements to be of type xsd:anyURI using esql. output should be like given above:
I assume that you are asking about the xsi:type attribute. The XMLNSC parser does not automatically populate the namespace prefix in the value of the xsi:type attribute - you must set the entire value (prefix:localName) as a literal text string.
DECLARE namespace787 NAMESPACE 'http://ws.abc.efg.com';
DECLARE namespaceXSI NAMESPACE 'http://www.w3.org/2001/XMLSchema-instance';
CREATE LASTCHILD OF OutputRoot.XMLNSC.payload TYPE XMLNSC.Attribute NAMESPACE namespaceXSI NAME 'type' VALUE 'ns787:SomeRequest';
CREATE LASTCHILD OF OutputRoot.XMLNSC.payload TYPE XMLNSC.NamespaceDecl NAME 'xmlns:ns787' VALUE namespace787;
or, if you prefer using SET instead of CREATE:
...
SET OutputRoot.XMLNSC.payload.(XMLNSC.Attribute)namespaceXSI:type = namespaceXSI;
SET OutputRoot.XMLNSC.payload.(XMLNSC.NamespaceDecl)xmlns:ns787 = namespace787;
If you are still stuck then you may find this technique useful: How to create a complex object in ESQL
In Xquery 3.1 (under eXist-DB 4.7) I receive xml data like this, with no namespace:
<edit-request id="TC9999">
<title-collection>foocolltitle</title-collection>
<title-exempla>fooextitle</title-exempla>
<title-short>fooshorttitle</title-short>
</edit-request>
This is assigned to a variable $content and this statement:
let $collid := $content/edit-request/#id
...correctly returns: TC9999
Now, I need to actually transform all the data in $content into a TEI xml document.
I first need to get some info from an existing TEI file, so I assigned another variable:
let $oldcontent := doc(concat($globalvar:URIdata,$collid,"/",$collid,".xml"))
And then I create the new TEI document, referring to both $content and $oldcontent:
let $xml := <listBibl xmlns="http://www.tei-c.org/ns/1.0"
type="collection"
xml:id="{$collid}">
<bibl>
<idno type="old_sql_id">{$oldcontent//tei:idno[#type="old_sql_id"]/text()}</idno>
<title type="collection">{$content//title-exempla/text()}</title>
</bibl>
</listBibl>
The references to the TEI namespace in $oldcontent come through, but to my surprise the references to $content (no namespace) don't show up:
<listBibl xmlns="http://www.tei-c.org/ns/1.0"
type="collection"
xml:id="TC9999">
<bibl>
<idno type="old_sql_id">1</idno>
<title type="collection"/>
</bibl>
</listBibl>
The question is: how do I refer to the non-namespace elements in $content in the context of let $xml=...?
Nb: the Xquery document has a declaration at the top (as it is the principle namespace of virtually all the documents):
declare namespace tei = "http://www.tei-c.org/ns/1.0";
In essence you are asking how to write an XPath expression to select nodes in an empty namespace in a context where the default element namespace is non-empty. One of the most direct solutions is to use the "URI plus local-name syntax" for writing QNames. Here is an example:
xquery version "3.1";
let $x := <x><y>Jbrehr</y></x>
return
<p xmlns="foo">Hey there,
{ $x/Q{}y => string() }!</p>
If instead of $x/Q{}y the example had used the more common form of the path expression, $x/y, its result would have been an empty sequence, since the local name y used to select the <y> element specifies no namespace and thus inherits the foo element namespace from its context. By using the "URI plus local-name syntax", though, we are able to specify the empty namespace we are looking for.
For more information on this, see the XPath 3.1 specification's discussion of expanded QNames: https://www.w3.org/TR/xpath-31/#doc-xpath31-EQName.
Is it possible to check two or more variables when mocking a response using SoapUi?
Here's a sample of the request:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:crm="http://www.example.com/project/wsdl/crm/">
<soap:Body>
<crm:SearchCustomer>
<FirstName>Francis</FirstName>
<LastName>Zabala</LastName>
</crm:SearchCustomer>
</soap:Body>
</soap:Envelope>
Here's the Extract Xpath
declare namespace crm='http://www.example.com/project/wsdl/crm/';
declare namespace soap='http://www.w3.org/2003/05/soap-envelope';
//crm:SearchCustomer[1]/FirstName
Expected value:
Francis
What about if I also want to check the last name?
You can try using the follow XPath expression which check for the text content of the <FirstName> and <LastName> and use boolean() XPath function to check if the expression it's accomplished or not. Also SOAPUI supports the use of * as a wildcard for namespaces so your expression could be:
boolean(//*:FirstName[text() = 'Francis'] and //*:LastName[text() = 'Zabala'])
And as expected value:
true
I have as second of xml
<Environment
Name="test"
xmlns="http://schemas.dmtf.org/ovf/environment/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
oe:id="123456789">
<PropertySection>
<Property oe:key="mykey" oe:value="test"/>
</PropertySection>
</Environment>
I'm using ruby and nokogiri to parse the document. i.e.
file = File.open('/tmp/myxml.xml')
doc = Nokogiri::XML(file)
env = doc.at('Environment')
id = env['id']
printf("ID [%s]\n", id)
properties = env.at('PropertySection')
This works and successfully prints the id from the xml.
I now want to access the Property attribute with the key 'mykey'. I tried the following:
value = properties.at('Property[#key="mykey"]')['value']
printf("Value %s\n", value)
Unfortunately the properties.at method returns a nil object. I tried modifying the xml itself to remove the 'oe' namespace from the attribute 'key'. Re-running my script it works.
How can I get nokogiri to recognise the namespace when calling .at() ?
You should use the Nokogiri namespace syntax: http://nokogiri.org/tutorials/searching_a_xml_html_document.html#namespaces.
First, make sure you have namespaces you can use:
ns = {
'xmlns' => 'http://schemas.dmtf.org/ovf/environment/1',
'oe' => 'http://schemas.dmtf.org/ovf/environment/1'
}
(I'm defining both even though they are the same in this example). You might also look into using the namespaces already available in doc.collect_namespaces.
Then you can just do:
value = properties.at('./xmlns:Property[#oe:key="mykey"]/#oe:value', ns).content
Note that I am using ./ here because, for this specific search, Nokogiri interprets the XPath as CSS without it. You may wish to use .//.