Piwik statitics about all websites - api

Is it possible to use the Piwik-API with all Websites, not just for a single one?
What i want to do is get a mean value of used browsers. I can do this for a single website like this:
?module=API&method=UserSettings.getBrowser&idSite=1&period=day&date=last10&format=rss
If i just remove idSite=1 i get an error.

You can specify all sites using idSite=all, you can also specify multiple sites by separating the ids with commas idSite=1,2,4,5.
The resulting output is given per idSite wrapped in an extra <results> tag, so whereas before you had
<result>
<row>
<label>Chrome 14.0</label>
<nb_uniq_visitors>13</nb_uniq_visitors>
...
</row>
<row>
<label>Chrome 13.0</label>
<nb_uniq_visitors>13</nb_uniq_visitors>
...
</row>
...
</result>
You now get
<results>
<result idSite="2">
<row>
<label>Chrome 14.0</label>
<nb_uniq_visitors>13</nb_uniq_visitors>
...
</row>
<row>
<label>Chrome 13.0</label>
<nb_uniq_visitors>13</nb_uniq_visitors>
...
</row>
...
</result>
<result idSite="3">
<row>
<label>Chrome 14.0</label>
<nb_uniq_visitors>13</nb_uniq_visitors>
...
</row>
<row>
<label>Chrome 13.0</label>
<nb_uniq_visitors>13</nb_uniq_visitors>
...
</row>
...
</result>
...
</results>
This does mean that any aggregating for your mean value will have to be done once you get the data but this should be relatively trivial.

Related

Group by ID and Sum Amount in XSLT

I'm fairly new to XSLT and stuck on a current problem. I've done some searches throughout Stackflow (seems like Muenchian method is the common group method) but I can't seem to mimic some of the posted ideas as of yet.
So I'm using a line item read system of which I'm trying to write code in XSLT to read every line to check if the supplier ID is the same, if true, it will aggregate this into one line, then sum the amounts. If not true, it should start a new line with the ID and sum the amount and so forth. I am using xml version='1.0'
Below is my current data file in XML:
<data>
<row>
<column1>06-11111</column1>
<column2>CP</column2>
<column3>744.04</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11111</column1>
<column2>CP</column2>
<column3>105.09</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11111</column1>
<column2>CP</column2>
<column3>1366.24</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11111</column1>
<column2>CP</column2>
<column3>485.71</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11112</column1>
<column2>Ever</column2>
<column3>459.60</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11112</column1>
<column2>Ever</column2>
<column3>409.14</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11112</column1>
<column2>Ever</column2>
<column3>397.12</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11113</column1>
<column2>GE</column2>
<column3>1425</column3>
<column4>CAD</column4>
</row>
<row>
<column1>06-11114</column1>
<column2>Husky</column2>
<column3>-215.14</column3>
<column4>USD</column4>
</row>
<row>
<column1>06-11114</column1>
<column2>Husky</column2>
<column3>2015</column3>
<column4>USD</column4>
</row>
<row>
<column1>06-11114</column1>
<column2>Husky</column2>
<column3>11195.34</column3>
<column4>USD</column4>
</row>
</data>
The output I would like to achieve after running the XSLT is
06-11111 | CP |2701.08
06-11112 | Ever |1265.86
06-11113 | GE |1425
06-11114 | Husky |12995.20
Any help to get me started would be fantastic!
Here is the grouping using the Muenchian method. I'll let you play with getting the numbers formatted correctly based on the number of decimal points.
I typically don't use this because it's limited, tricky and doesn't lend itself to push programming. But, it will work for you today.
<xsl:template match="#* | node()">
<xsl:apply-templates select="#* | node()"/>
</xsl:template>
<xsl:key name="rows" match="row" use="concat(column1, '||', column2)" />
<xsl:template match="data">
<xsl:for-each select="row[generate-id(.) = generate-id(key('rows', concat(column1, '||', column2))[1])]">
<xsl:sort select="column1" data-type="text" order="ascending"/>
<xsl:sort select="column2" data-type="text" order="ascending"/>
<xsl:value-of select="concat(column1,'|',column2,'|')"/>
<xsl:variable name="mySum">
<xsl:value-of select="sum(key('rows', concat(column1, '||', column2))/column3)"/>
</xsl:variable>
<xsl:value-of select="format-number($mySum,'#,##0.00')"/>
<xsl:value-of select="'
'"/>
</xsl:for-each>
</xsl:template>

How to get Xpath Value in Hive

I wanted to get the value of Hindi & English as an arry from the below xml using XPATH in Hive.
<employees>
<employee>
<name>Ranjith</name>
<language emp:langCode="HI">Hindi</language>
<city emp:country="india">Delhi</city>
<employee>
<employee>
<name>John</name>
<language emp:langCode="EN">English</language>
<city emp:country="america">Sunnyvale</city>
<employee>
</employees>
Can anyone help??
I have tried few options, but not works.
Generic xpath would be:
/employees/employee/language
But your xml has some errors in it. Here is the updated xml that works:
<employees>
<employee>
<name>Ranjith</name>
<language langCode="HI">Hindi</language>
<city country="india">Delhi</city>
</employee>
<employee>
<name>John</name>
<language langCode="EN">English</language>
<city country="america">Sunnyvale</city>
</employee>
</employees>
And here is the result using the shown xpath
Element='<language langCode="HI">Hindi</language>'
Element='<language langCode="EN">English</language>'

XSL v.1, Muenchian Grouping, Summing Line Items per Invoice, Call-Template

I'm trying to sum the aggregate of line item amounts in a group with multiple groups. That is, there are many Invoices with many Line Items per Invoice. I need to sum the Amounts of Line Items across each Invoice.
I've searched across various posts here on Stack, as well as various forums, and haven't been able to decipher the code to be able to sum values with a Muenchian Grouping approach. If there is already a solution for this, please point me in the right direction.
The grouping occurs on the recordId attribute.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<query>
<results total="6">
<result recordId="15918960" associatedRecordId="null" boId="10002385">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount_display><![CDATA[$20.74]]></LI_Amount_display>
</column>
</columns>
</result>
<result recordId="15918960" associatedRecordId="null" boId="10002385">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount_display><![CDATA[$30.74]]></LI_Amount_display>
</column>
</columns>
</result>
<result recordId="15918960" associatedRecordId="null" boId="10002385">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount_display><![CDATA[$40.74]]></LI_Amount_display>
</column>
</columns>
</result>
<result recordId="15918961" associatedRecordId="null" boId="10002385">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount_display><![CDATA[$20.74]]></LI_Amount_display>
</column>
</columns>
</result>
<result recordId="15918961" associatedRecordId="null" boId="10002385">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount_display><![CDATA[$30.74]]></LI_Amount_display>
</column>
</columns>
</result>
<result recordId="15918962" associatedRecordId="null" boId="10002385">
<columns>
<column>
<field>AmountNU</field>
<LI_Amount_display><![CDATA[$29.74]]></LI_Amount_display>
</column>
</columns>
</result>
</results>
</query>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:datetime="http://exslt.org/dates-and-times"
xmlns:exsl="http://exslt.org/common"
xmlns:fn="http://www.w3.org/2013/xpath-functions"
exclude-result-prefixes="datetime">
<xsl:output method="text" encoding="UTF-8" indent="no"/>
<xsl:key name="recordID" match="result" use="#recordId"/><!-- Define a key to use for grouping the results -->
<!-- Might be needed for nulls
<xsl:template match="/results/result/columns/column/LI_Amount_display[not(text()[normalize-space()])]">
<xsl:element name='LI_Amount_display' value="0.00"></xsl:element>
</xsl:template> -->
<xsl:template match="/">
<xsl:call-template name="fixTheWidth" >
<!-- This parameter is a Id for each group of records based on the result/#recordId attribute. This groups all records to the record ID-->
<xsl:with-param name="resultIndex" select="//results/result[generate-id(.) = generate-id(key('recordID', #recordId)[1])]" />
</xsl:call-template>
</xsl:template>
<xsl:template name="fixTheWidth" match="/results">
<xsl:param name="resultIndex" /> <!-- A unique index based on grouping the records on the recordID -->
<!-- MORE CODE HERE USING $resultIndex has been redacted for simplicity-->
<xsl:for-each select="$resultIndex" >
<xsl:text> BEGIN | </xsl:text>
<xsl:value-of select="number(translate(substring(key('recordID',#recordId)/columns/column/LI_Amount_display,2),',',''))"></xsl:value-of>
<!-- <xsl:value-of select="sum(number(translate(substring(key('recordID',#recordId)/columns/column/LI_Amount_display,2),',','')))"></xsl:value-of>-->
</xsl:for-each>
<xsl:text> | END </xsl:text>
<!-- MORE CODE HERE USING $resultIndex has been redacted for simplicity-->
</xsl:template>
</xsl:stylesheet>
I realize that using the "call-template" strategy is not necessarily the "best" approach, but its what I've come to such that I can create a fixed width flat file and not have to refactor the entire script. If there's a way to accomplish this otherwise, I'm all ears.
You cannot sum nodes that aren't numbers. A value of $20.74 is a string, not a number. You must first convert the values to numbers by removing the currency symbol (and any other non-numeric characters, if they are allowed in the input), then proceed to group the resulting nodes and sum the groups.
Here's an example:
XSLT 1.0
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="amt" match="amount" use="#id"/>
<xsl:template match="/query">
<xsl:variable name="amounts">
<xsl:for-each select="results/result">
<amount id="{#recordId}"><xsl:value-of select="translate(columns/column/LI_Amount_display, '$', '')"/></amount>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="amount-set" select="exsl:node-set($amounts)/amount" />
<xsl:for-each select="$amount-set[generate-id() = generate-id(key('amt', #id)[1])]" >
<xsl:text> BEGIN | </xsl:text>
<xsl:value-of select="sum(key('amt', #id))"/>
</xsl:for-each>
<xsl:text> | END </xsl:text>
</xsl:template>
</xsl:stylesheet>
Applied to your example input, the result is:
BEGIN | 92.22 BEGIN | 51.48 BEGIN | 29.74 | END
I couldn't understand the strategy of calling a template and "create a fixed width flat file". In any case, it seems unrelated to the question at hand. You might post a separate question, if necessary.

how to select preceding nodes within a specific parent

Given the following xml
<Root>
<Employee>
<service>
<Record>xxx</Record>
<Record>yyy</Record>
</service>
<service>
<Record>xxx</Record>
<Record>yyy</Record>
<Record>zzz</Record>
</service>
</Employee>
<Employee>
<service>
<Record>xxx</Record>
<Record>yyy</Record>
</service>
<service>
<Record>xxx</Record>
<Record>yyy</Record>
<Record>zzz</Record>
</service>
</Employee>
</Root>
Using XSLT1.0, while transforming the xml for each <Employee> the <Record> field containing 'xxx','yyy','zzz' should occur only once in the result
<Root>
<Employee>
<Service>
<Record>xxx</Record>
<Record>yyy</Record>
<Record>zzz</Record>
</Service>
</Employee>
<Employee>
<Service>
<Record>xxx</Record>
<Record>yyy</Record>
<Record>zzz</Record>
<Service>
</Employee>
</Root>
In a for-each loop of Employee I tired using <xsl:if test='not(preceding::./service/Record=$record)'>. The test works fine for the first <Employee> taking the <Record> for 'xxx','yyy','zzz' only once. When the iteration goes to the next <Employee> the test condition checks for the <Record>values in the first<Employee> also and it finds preceding nodes already exisitng with the values'xxx','yyy','zzz', hence i am not able to get the records for the second <Employee>.
How to get the <Record>s in the second <Employee> . Any help is much appreciated.
Thanks
This transformation uses the Muenchian method for grouping:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kEmpRecordByVal" match="Employee/service/Record"
use="concat(generate-id(../..), '+', .)"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Employee">
<Employee>
<xsl:apply-templates select=
"service/Record
[generate-id()
=
generate-id(key('kEmpRecordByVal',
concat(generate-id(../..), '+', .)
)[1]
)
]
"/>
</Employee>
</xsl:template>
</xsl:stylesheet>
when applied on the following XML document (the provided one with different values for the second Employee to aid readability):
<Root>
<Employee>
<service>
<Record>xxx</Record>
<Record>yyy</Record>
</service>
<service>
<Record>xxx</Record>
<Record>yyy</Record>
<Record>zzz</Record>
</service>
</Employee>
<Employee>
<service>
<Record>aaa</Record>
<Record>bbb</Record>
</service>
<service>
<Record>aaa</Record>
<Record>bbb</Record>
<Record>ccc</Record>
</service>
</Employee>
</Root>
the wanted, correct result is produced:
<Root>
<Employee>
<Record>xxx</Record>
<Record>yyy</Record>
<Record>zzz</Record>
</Employee>
<Employee>
<Record>aaa</Record>
<Record>bbb</Record>
<Record>ccc</Record>
</Employee>
</Root>

Oracle SQL*Loader getting CDATA values

Anybody knows how to do this? I know there's a better way of loading XML data to Oracle without using SQL*Loader, but I'm just curious on how this is done using it. I have already a code that can load XML data to the DB, however, it wont run if the XML file has values that contain a CDATA...
Below is the control file code which works if the values are not CDATA...
LOAD DATA
INFILE FRATS.xml "str '</ROW>'"
APPEND
INTO TABLE "FRATERNITIES"
(
DUMMY FILLER TERMINATED BY "<ROW>",
THE_CODE SEQUENCE (MAX, 1),
DUMMY2 FILLER TERMINATED BY "</COLUMN>",
STORE_NN_KJ ENCLOSED BY '<COLUMN NAME="THE_NAME">' AND '</COLUMN>',
STAFF_COUNT ENCLOSED BY '<COLUMN NAME="THE_COUNT">' AND '</COLUMN>'
)
Here's the XML file:
<?xml version='1.0' encoding='MS932' ?>
<RESULTS>
<ROW>
<COLUMN NAME="THE_CODE">777</COLUMN>
<COLUMN NAME="THE_NAME">CharlieOscarDelta</COLUMN>
<COLUMN NAME="THE_COUNT">24</COLUMN>
</ROW>
</RESULTS>
Here's the XML file with CDATA values. My control file will not run with it...:
<?xml version='1.0' encoding='MS932' ?>
<RESULTS>
<ROW>
<COLUMN NAME="THE_CODE"><![CDATA[777]]></COLUMN>
<COLUMN NAME="THE_NAME"><![CDATA[CharlieOscarDelta]]></COLUMN>
<COLUMN NAME="THE_COUNT"><![CDATA[24]]></COLUMN>
</ROW>
</RESULTS>
have you tried
STORE_NN_KJ "substr(substr(:STORE_NN_KJ,instr(:STORE_NN_KJ,'<![CDATA[')+9),0,instr(substr(:STORE_NN_KJ,instr(:STORE_NN_KJ,'<![CDATA[')+9),']]>'))" ENCLOSED BY '<COLUMN NAME="THE_NAME">' AND '</COLUMN>'
EDIT
Looks like I forgot a ).. Try this..