XQuery: How to get a specific value out of a tag? - return

Suppose we have this xml:
<question>
<test id="1">
<tag k="a" v="1"/>
<tag k="a" v="2"/>
<tag k="b" v="3"/>
</test>
<test id="2">
<tag k="a" v="1"/>
<tag k="a" v="4"/>
<tag k="b" v="5"/>
</test>
<test id="3">
<tag k="a" v="2"/>
<tag k="a" v="6"/>
<tag k="b" v="7"/>
</test>
</question>
I would like to return all values v of test, if k = "a" AND v = "1", like this:
v="3"
v="5"
So far my approach:
for $i in //test
where ($i/tag[#k = 'a' and #v = '1'])
return $i/tag/#v
But this is not correct because thats the return:
v="1"
v="2"
v="3"
v="1"
v="4"
v="5"
Thank you for your help :)

You are probably looking for something like
for $i in //test
where ($i/tag[#k = 'a'][#v="1"])
return $i/tag[#k="b"]/#v

Your criteria for selection was not exactly clear, but this returns what you expected:
for $i in //test
where $i/tag[#k = 'a' and #v = '1']
return $i/tag[not(#k = 'a' or #v = '1')]/#v
You could simplify and do this in a single XPath expression:
//test/tag[#k = 'a' and #v = '1']/tag[not(#k = 'a' or #v = '1')]/#v

Related

unable to parse xml with groovy

I can't read the xml and parse the items because it's always returning an error of
groovy.lang.MissingPropertyException: No such property: method for
class: Script1
def xmlText = new XmlSlurper().parse('myxml.xml')
def skipped = 0
def failed = 0
def total = 0
def passed = 0
xmlText.suite.test.class.test-method.each{
if(it['#is-config'] == "true"){
}
else{
if(it['#status']=="PASS"){
passed = passed + 1
total = total + 1
}
if(it['#status']=="FAIL"){
failed = failed + 1
total = total + 1
}
if(it['#status']=="SKIP"){
skipped = skipped + 1
total = total + 1
}
}
}
the xml file is
<?xml version="1.0" encoding="UTF-8"?>
<testng-results skipped="3" failed="0" total="3" passed="0">
<reporter-output>
</reporter-output>
<suite name="DinamicTestSuite" duration-ms="24" started-at="2018-07-16T13:26:48Z" finished-at="2018-07-16T13:26:48Z">
<groups>
</groups>
<test name="Device:null" duration-ms="24" started-at="2018-07-16T13:26:48Z" finished-at="2018-07-16T13:26:48Z">
<class name="com.automation.venues.stg.VenuesSuite">
<test-method status="PASS" signature="login(org.testng.ITestContext, java.lang.String)[pri:0, instance:com.automation.venues.stg.VenuesSuite#71454b9d]" name="login" is-config="true" duration-ms="11" started-at="2018-07-16T16:26:48Z" finished-at="2018-07-16T16:26:48Z">
</test-method>
<test-method status="PASS" signature="beforeMethod(java.lang.reflect.Method)[pri:0, instance:com.automation.venues.stg.VenuesSuite#71454b9d]" duration-ms="0" started-at="2018-07-16T16:26:48Z" finished-at="2018-07-16T16:26:48Z">
</test-method>
</class> <!-- com.automation.venues.stg.VenuesSuite -->
</test> <!-- Device:null -->
</suite> <!-- DinamicTestSuite -->
</testng-results>
how can I parse the list ?
You need to put quotes round the attribute with a - in it
xmlText.suite.test.class.'test-method'.each{
An alternative to your each approach would be:
def xmlText = new XmlSlurper().parse('myxml.xml')
def totals = xmlText.suite.test.class.'test-method'.countBy { it.#status.text() }
def skipped = totals.SKIP
def failed = totals.FAIL
def passed = totals.PASS
def total = totals.values().sum()

XPATH in Nokogiri

I have an XML + SOAP with Nokogiri and I want only the body to appear but I have some errors.
The XML SOAP is:
data = <SOAP:Envelope xmlns:SOAP=\"http://schemas.xmlsoap.org/soap/envelope/\">
<SOAP:Header><header xmlns=\"xmlapi_1.0\">
<requestID>aquiroga:0001</requestID>
<requestTime>Mar 14, 2018 11:33:27 PM</requestTime>
<responseTime>Mar 14, 2018 11:33:27 PM</responseTime>
</header>
</SOAP:Header>
<SOAP:Body>
<findResponse xmlns=\"xmlapi_1.0\">
<result>
<service.SapEgrQosQueueStatsLogRecord>
<queueId>2</queueId>
<droppedInProfOctets>0</droppedInProfOctets>
<droppedOutProfOctets>0</droppedOutProfOctets>
<timeCaptured>1521072355115</timeCaptured>
<periodicTime>0</periodicTime>
<displayedName>eNodo_B-HOTELPUERTOPALMERA-S1UX2</displayedName>
<monitoredObjectSiteName>SMT-TRS-AN01</monitoredObjectSiteName>
</service.SapEgrQosQueueStatsLogRecord>
<service.SapEgrQosQueueStatsLogRecord>
<queueId>1</queueId>
<droppedInProfOctets>0</droppedInProfOctets>
<droppedOutProfOctets>70450698</droppedOutProfOctets>
<timeCaptured>1521072355051</timeCaptured>
<periodicTime>199796</periodicTime>
<displayedName>to_eNODOB Tarapoto Sur-S1-MME</displayedName>
<monitoredObjectSiteName>SMT-TRS-AN01</monitoredObjectSiteName>
</service.SapEgrQosQueueStatsLogRecord>
</result>
</findResponse>
</SOAP:Body>
</SOAP:Envelope>
The code I am using is:
data_stats = data.xpath('/SOAP:Envelope/SOAP:Body')
The result is:
=> #<Nokogiri::XML::Element:0x3fee745c1c94 name="Body" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1e60 prefix="SOAP" href="http://schemas.xmlsoap.org/soap/envelope/"> children=[#<Nokogiri::XML::Element:0x3fee745c16b8 name="findResponse" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Element:0x3fee745c126c name="result" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Element:0x3fee745c0e84 name="service.SapEgrQosQueueStatsLogRecord" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Element:0x3fee745c0a60 name="queueId" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Text:0x3fee745c0664 "1">]>, #<Nokogiri::XML::Element:0x3fee745c0498 name="droppedInProfOctets" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Text:0x3fee745c00b0 "0">]>, #<Nokogiri::XML::Element:0x3fee745adec4 name="droppedOutProfOctets" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Text:0x3fee745adaa0 "0">]>, #<Nokogiri::XML::Element:0x3fee745ad8d4 name="timeCaptured" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Text:0x3fee745ad4c4 "1521158716279">]>, #<Nokogiri::XML::Element:0x3fee745ad2f8 name="periodicTime" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Text:0x3fee745aceac "284992">]>, #<Nokogiri::XML::Element:0x3fee745acce0 name="displayedName" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Text:0x3fee745ac8bc "RTN VillaSalvador3 Tdp-VillaBaja">]>, #<Nokogiri::XML::Element:0x3fee745ac6dc name="monitoredObjectSiteName" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0"> children=[#<Nokogiri::XML::Text:0x3fee745ac2b8 "LIM-SPO-AN02">]>]>, #<Nokogiri::XML::Element:0x3fee74593f9c name="service.SapEgrQosQueueStatsLogRecord" namespace=#<Nokogiri::XML::Namespace:0x3fee745c1668 href="xmlapi_1.0">
I want it to appear only from service.SapEgrQosQueueStatsLogRecord. The code I use is the following:
data_stats = qos7705egressdiscard_summary.xpath('/SOAP:Envelope/SOAP:Body/findResponse/result/service.SapEgrQosQueueStatsLogRecord')
But the result is an empty arrangement => []
You can use data.remove_namespaces! ( see http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document:remove_namespaces! ). Then this query works:
data.xpath('/Envelope/Body/findResponse/result/service.SapEgrQosQueueStatsLogRecord')

Two collections in for each

How to specify two collection variables in foreach scope in mule?
<foreach collection="#[flowVars.ar] && #[flowVars.md]" doc:name="For Each" counterVariableName="i">
<db:select config-ref="Generic_Database_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[SELECT a.tempocode AS tempocode
FROM Referencelookup a WITH (NOLOCK)
JOIN ReferenceLookup r WITH (NOLOCK) ON r.Metadatatype = 'ServicerCode' AND r.TempoCode = a.AccountName
WHERE a.metadatatype =#[flowVars.md[counter-1]]
AND a.lookuptype = 'fiserv' AND r.refcode =#[flowVars.srvcode] AND a.refcode =#[flowVars.ar[counter-1]]]]></db:parameterized-query>
</db:select>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</foreach>

Else Loop only runs once

I'm running an else loop to iterate through an XML file in ruby, assigning values to a hash. There are 3 items in the XML file, but for some reason it only iterates through the first one, any idea why?
require "nokogiri"
f= File.open("untitled.xml")
doc = Nokogiri::XML(f)
f.close
doc.xpath('//item').each do |node|
children = node.children
item = {
"name" => node['name'],
"buyItNowPrice"=> children.css('buytItNowPrice').inner_text,
"description" => children.css('description').inner_text,
"startingBidPrice" => children.css('startingBidPrice').inner_text,
"closing_time" => children.css('closing_time').inner_text,
"closing_date" => children.css('closing_date').inner_text
}
puts item
end
XML:
<item name = "Test Thing">
<description>Something Coolest.</description>
<buytItNowPrice>154.99</buytItNowPrice>
<startingBidPrice>9999.99</startingBidPrice>
<closing_date>2014-12-25</closing_date>
<closing_time>12:32:PM</closing_time>
</item>
<item name = "Lazer">
<description>Something Cool.</description>
<buytItNowPrice>149.99</buytItNowPrice>
<startingBidPrice>9.99</startingBidPrice>
<closing_date>2014-12-25</closing_date>
<closing_time>12:32:PM</closing_time>
</item>
<item name = "Pokemon">
<description>Something even cooler.</description>
<buytItNowPrice>33.99</buytItNowPrice>
<startingBidPrice>9.99</startingBidPrice>
<closing_date>2014-12-25</closing_date>
<closing_time>12:32:PM</closing_time>
</item>
Output is only the the first item printed.
The given sample XML isn't valid.
A valid XML document requires a single root node, right now you have 3.
You could fix this by wrapping all the <item> nodes in a <items> root node, and iterate through its children then.

Parsing with Ruby Mechanize

Im trying to parse a website using the Mechanize Gem. So far this is what I have:
page = agent.get("http://www.greatgiftsformen.com/price-range-under-c-131_142.html?page=all")
page.parser.xpath('//tr[(((count(preceding-sibling::*) + 1) = 2) and parent::*)]//*[contains(concat( " ", #class, " " ), concat( " ", "productListing-data", " " ))]')[5]
and I get the elements for this product back:
=> #<Nokogiri::XML::Element:0x81c175ec name="td" attributes=[#<Nokogiri::XML::Attr:0x81c17d58 name="valign" value="top">, #<Nokogiri::XML::Attr:0x81c17eac name="align" value="center">, #<Nokogiri::XML::Attr:0x81c17ec0 name="class" value="productListing-data">] children=[#<Nokogiri::XML::Element:0x805fa174 name="a" attributes=[#<Nokogiri::XML::Attr:0x81c13794 name="href" value="http://www.greatgiftsformen.com/gas-pump-retro-liquor-dispenser-p-249.html?osCsid=05f5dbb816874ece6db883c2c48d7ae1">] children=[#<Nokogiri::XML::Element:0x8068e270 name="img" attributes=[#<Nokogiri::XML::Attr:0x81c115ac name="src" value="product_thumb.php?img=images/prod/liquordisp-gas.jpg&w=160&h=160">, #<Nokogiri::XML::Attr:0x81c115c0 name="width" value="160">, #<Nokogiri::XML::Attr:0x81c115d4 name="height" value="160">, #<Nokogiri::XML::Attr:0x81c11714 name="border" value="0">, #<Nokogiri::XML::Attr:0x81c11728 name="alt" value="Gas Pump Retro Liquor Dispenser">, #<Nokogiri::XML::Attr:0x81c11750 name="title" value="Gas Pump Retro Liquor Dispenser">, #<Nokogiri::XML::Attr:0x81c11764 name="class" value="fotgal">]>]>]>
however when I try to get the href, I get back nil:
url = item.attributes['href']
=> nil
Needed to add the child nodes:
url = item.children[0].attributes['href'].to_s

Resources