I have following xml :
<note>
<para>customer name :</para>
<para>mr. Joe Someone</para>
<para>calling from :</para>
<para>1234567</para>
<para>device model :</para>
<para>ABC-123</para>
<para>issue:</para>
<para>some info</para>
<para>some more info</para>
<para>and even more info</para>
<para>solution :</para>
<para>some solutions</para>
<para>and some more solutions</para>
</note>
and I would like to group on every node where the text ends with a doubledot, so the result would become something like below :
<note>
<para>customer name :</para>
<groupdata>
<para>mr. Joe Someone</para>
</groupdata>
<para>calling from :</para>
<groupdata>
<para>1234567</para>
</groupdata>
<para>device model :</para>
<groupdata>
<para>ABC-123</para>
</groupdata>
<para>issue:</para>
<groupdata>
<para>some info</para>
<para>some more info</para>
<para>and even more info</para>
</groupdata>
<para>solution :</para>
<groupdata>
<para>some solutions</para>
<para>and some more solutions</para>
</groupdata>
</note>
What would be the most efficient approach (using xslt 2.0) ?
I think using xsl:for-each-group select="*" group-starting-with="*[ends-with(., ':')]" is straight-forward:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="note">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="*[ends-with(., ':')]">
<xsl:copy-of select="."/>
<groupdata>
<xsl:copy-of select="current-group() except ."/>
</groupdata>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Efficiency is something you would have to measure for each implementation.
Related
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
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')
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>
I have a XML file in this format:
<league country="argentina" name="Argentina: Torneo Federal A - Winners Stage" cup="False" id="2909" sub_id="29094">
<match alternate_id="4187269" alternate_id_2="4394549" date="14.08.2015" id="4304775" static_id="14081523515562337775" status="FT" time="18:00">
<home goals="2" id="2351556" name="Club Atletico Mitre"></home>
<away goals="1" id="2337775" name="Chaco For Ever"></away>
<events>
<event assist="" assistid="" id="22958994" minute="32" player="Juan Pablo Villafane" playerid="" result="[1 - 0]" team="home" type="goal"></event>
<event assist="" assistid="" id="22958995" minute="48" player="Aldo Visconti" playerid="" result="[1 - 1]" team="away" type="goal"></event>
<event assist="" assistid="" id="22958996" minute="90" player="Emanuel Lazzarini" playerid="" result="[2 - 1]" team="home" type="goal"></event>
</events>
<ht score="[1-0]"></ht>
<ft score="[2-1]"></ft>
</match></league><league country="argentina" name="Argentina: Torneo Federal A - Losers Stage" cup="False" id="2909" sub_id="29095"><match alternate_id="4178253" alternate_id_2="4410516" date="14.08.2015" id="4295774" static_id="14081523557572337894" status="FT" time="18:00">
<home goals="2" id="2355757" name="Velez de San Ramon"></home>
<away goals="1" id="2337894" name="Sportivo Patria"></away>
<events>
<event assist="" assistid="" id="23118664" minute="11" player="Diego Suarez" playerid="" result="[1 - 0]" team="home" type="goal"></event>
<event assist="" assistid="" id="23118665" minute="64" player="Luis Leguizamon" playerid="" result="[2 - 0]" team="home" type="goal"></event>
<event assist="" assistid="" id="23118666" minute="67" player="Rodrigo Ramirez (o.g.)" playerid="" result="[2 - 1]" team="away" type="goal"></event>
</events>
<ht score="[1-0]"></ht>
<ft score="[2-1]"></ft>
This is my controller:
xml = Nokogiri::XML(f)
path = "//match[#static_id='user.matchid']"
#country = xml.xpath(path)
How can I get the name of team, based on the condition that value of attribute "result" = [1-0] or [0-1]?
I'd do something like:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<xml>
<league>
<match>
<events>
<event player="Juan Pablo Villafane" result="[1 - 0]" team="home"></event>
<event player="Aldo Visconti" result="[1 - 1]" team="away"></event>
</events>
<events>
<event player="Diego Suarez" result="[1 - 0]" team="home"></event>
<event player="Luis Leguizamon" result="[2 - 0]" team="home"></event>
</events>
</match>
</league>
</xml>
EOT
doc.search('//event[contains(#result, "[1 - 0]") or contains(#result, "[0 - 1]")]/#team').map(&:text)
# => ["home", "home"]
It isn't stated clearly what is the condition to check exactly. So, here is an example condition for context, suppose you want to get name of home team of a match where final time score is "[2-1]" :
//match[ft/#score = '[2-1]']/home/#name
I am trying to create an XLS sheet programmatically. I am able to create single sheet in the XLS file, but when I try to create two sheets, I get the error. The file is created but I am unable to open the file. I can only open the file when it is created with single sheet.
Here is what I tried:
RSworkBook * folder = [ [RSworkBook alloc] init];
folder.author = #"andrea cappellotto";
folder.version = 1.2;
RSworkSheet * sheet = [[RSworkSheet alloc] initWithName:#"prova"];
RSworkSheet * sheet2 = [[RSworkSheet alloc] initWithName:#"222"];
RSworkSheetRow * row = [[RSworkSheetRow alloc] initWithHeight:20];
[row addCellString:#"prova"];
[row addCellString:#"prova2"];
[sheet addWorkSheetRow:row];
[sheet2 addWorkSheetRow:row];
RSworkSheetRow * row2 = [[RSworkSheetRow alloc] initWithHeight:25];
[row2 addCellNumber:100];
[row2 addCellData:[NSDate date] ];
[sheet addWorkSheetRow:row2];
[sheet2 addWorkSheetRow:row];
[folder addWorkSheet:sheet];
[folder addWorkSheet:sheet2];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
[folder writeWithName:#"prova" toPath:documentsDir];
HEre is the xml code that is generated:
<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:x="urn:schemas-microsoft-com:office:excel">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>andrea cappellotto</Author>
<LastAuthor>andrea cappellotto</LastAuthor>
<Created>2015-07-09</Created>
<Version>1.20</Version>
</DocumentProperties>
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>20000</WindowHeight>
<WindowWidth>20000</WindowWidth>
<WindowTopX>0</WindowTopX>
<WindowTopY>0</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook><Styles><Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Center" ss:Horizontal="Center"/>
<Borders/>
<Font ss:FontName=".HelveticaNeueInterface-Regular" ss:Size="14.00" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s60">
<NumberFormat ss:Format="Short Date"/>
</Style>
</Styles>
<Worksheet ss:Name="prova">
<Table ss:ExpandedColumnCount="2" ss:ExpandedRowCount="2" x:FullColumns="1" x:FullRows="1" ss:DefaultColumnWidth="0.00" ss:DefaultRowHeight="20.00">
<Column ss:Width="80"/>
<Row ss:AutoFitHeight="0" ss:Height="20.00" >
<Cell>
<Data ss:Type="String">prova</Data>
</Cell>
<Cell>
<Data ss:Type="String">prova2</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0" ss:Height="25.00" >
<Cell>
<Data ss:Type="Number">100.00</Data>
</Cell>
<Cell ss:StyleID="s60">
<Data ss:Type="DateTime">2015-07-09</Data>
</Cell>
</Row>
</Table>
<WorksheetOptions/>
</Worksheet>
<Worksheet ss:Name="222">
<Table ss:ExpandedColumnCount="2" ss:ExpandedRowCount="2" x:FullColumns="1" x:FullRows="1" ss:DefaultColumnWidth="0.00" ss:DefaultRowHeight="20.00">
<Column ss:Width="80"/>
<Row ss:AutoFitHeight="0" ss:Height="20.00" >
<Cell>
<Data ss:Type="String">prova</Data>
</Cell>
<Cell>
<Data ss:Type="String">prova2</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0" ss:Height="20.00" >
<Cell>
<Data ss:Type="String">prova</Data>
</Cell>
<Cell>
<Data ss:Type="String">prova2</Data>
</Cell>
</Row>
</Table>
<WorksheetOptions/>
</Worksheet>
</Workbook>
I found another library to create multiple sheets in a xls file. It is libxl.I can add as many sheets as I can by using the following line:
SheetHandle sheet = xlBookAddSheet(book, [sheetNAme UTF8String], NULL);