"count" field is always "1" with custom JavaScript YQL Open Data Table - yql

YQL returns the number of records retrieved in its XML output:
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="2" yahoo:created="2012-08-24T14:02:32Z" yahoo:lang="en-US">
<diagnostics>
But I've been experimenting with my own custom Open Data Tables, at least ones which employ an execute block containing JavaScript to create the response, and no matter how I create the response the count field is always set to 1 when I make a query using the table.
I've also dug around in the documentation and can't seem to find anything addressing this.
Is this by design? Is it a bug? Have I missed something obvious?

This is commonly caused by only returning one result, which shouldn't really come as a surprise. The most usual cause of this, from my own experience, is forgetting to specify a suitable itemPath for the <select>.
Take the following examples, and see how the response.object structure and itemPath combine to give the query results.
Without an itemPath
<select itemPath="" produces="XML">
<execute>
<![CDATA[
response.object = <letters>
<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
</letters>
]]>
</execute>
</select>
Produces a query result similar to:
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="1" yahoo:created="…" yahoo:lang="en-US">
<results>
<letters>
<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
</letters>
</results>
</query>
With itemPath="letters"
<select itemPath="letters" produces="XML">
…
</select>
Produces a query result identical to the previous result.
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="1" yahoo:created="…" yahoo:lang="en-US">
<results>
<letters>
<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
</letters>
</results>
</query>
With itemPath="letters.letter"
<select itemPath="letters.letter" produces="XML">
…
</select>
Note that now, the path now specifies a collection of letter items. This produces a query result similar to:
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="3" yahoo:created="…" yahoo:lang="en-US">
<results>
<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
</results>
</query>

Related

Scriptella: XML to DB: Insert Into from XPATH

I have an XML file that looks like this:
<XML>
<Table name='test'>
<Row>
<Field name='key'>1000</Field>
<Field name='text'>Test</Field>
</Row>
</Table>
</XML>
id like to parse this xml and use it within an insert statement:
<query connection-id="in">
/XML/Table/Row
<script connection-id="out">
INSERT INTO X t (
t.entitykey,
t.text
)
VALUES
(
????????
);
</script>
</query>
How do I access a specific Field-Tag from within the insert statement using XPATH?
We prefer to have one XSD that takes all table layouts into account and not to maintain n xsd for each table hence the Field[#name] design.
Thanks
Matthias
Xpath driver exposes a variable called node which provides a context for executing xpath expressions over a currently returned node. You can use the following expression to get the value of a particular field:
<script connection-id="out">
INSERT INTO X t (t.entitykey, t.text)
VALUES ( ?{node.getString("./Field[#name = 'text']")} );
</script>

Cannot get records for particular meeting

Cannot figure out how to properly send request to get all records, which are corresponding to the meeting.
From this request mysite.adobeconnect.com/api/xml?action=sco-info&sco-id=1087877981
I get such response:
<?xml version="1.0" encoding="utf-8"?>
<results>
<status code="ok"/>
<sco account-id="1051298934" disabled="" display-seq="0" folder-id="1057190786" icon="meeting" lang="en" max-retries="" sco-id="1087877981" source-sco-id="1051270965" type="meeting" version="3">
<date-begin>2013-08-20T03:15:00.000-07:00</date-begin>
<date-created>2013-08-20T03:30:04.200-07:00</date-created>
<date-end>2013-08-20T04:15:00.000-07:00</date-end>
<date-modified>2013-08-20T06:39:45.927-07:00</date-modified>
<name>DevTeam Meeting 2</name>
<url-path>/devmeeting2/</url-path>
<update-linked-item>true</update-linked-item>
</sco>
<source-sco>
<source-sco account-id="1051298934" disabled="" display-seq="0" folder-id="1051270964" icon="meeting" lang="en" max-retries="" sco-id="1051270965" source-sco-id="-8888" type="meeting" version="1">
<date-created>2012-05-15T14:09:07.453-07:00</date-created>
<date-modified>2013-08-13T16:33:57.600-07:00</date-modified>
<name>Default Meeting Template</name>
<url-path>/defaultmeetingtemplate/</url-path>
</source-sco></source-sco>
</results>
Where I see folder-id="1057190786" and sco-id="1087877981", but when I'm trying to get records for this meeting, using folder-id or sco-id according to documentation with requests
mysite.adobeconnect.com/api/xml?action=list-recordings&folder-id=1057190786
or
mysite.adobeconnect.com/api/xml?action=list-recordings&folder-id=1087877981
I receive:
<?xml version="1.0" encoding="utf-8"?>
<results>
<status code="invalid">
<invalid field="action" type="enum" subcode="no-such-item"/>
</status>
</results>
You should use another API method to get the recordings. They listed in the "scos" container, "url-path" element is what you need.
You should try the sco-contents method...
/api/xml?action=sco-contents&filter-icon=archive&sco-id=1087877981
Get your meeting contents calling sco-contents
You will find your records in those sco with icon="archive"
Don't use "list-recordings" as is not available anymore.
Reference (Sep. 20, 2016)
Provides a list of recordings (FLV and MP4) for a specified folder. The service and hence the API is no longer available.
Docs here.

Handling empty resultset from a query

I have two databases with the same structure and I want to compare records between databases. The records in second database are copied from the first database, but the copying process sometime doesn't work and in the first database in one table I have more records than in the same table in the second database. So I want to know which records from the first database doesn't exists in the second database. I have tried with something like that:
<etl>
<connection id="db1" driver="auto"
url="jdbc:mysql://localhost:3306/db" user="user"
password="xxx"
classpath="C:/mysql-connector-java-5.1.20.jar" />
<connection id="db2" driver="auto"
url="jdbc:mysql://localhost:3307/db" user="user"
password="xxx"
classpath="C:/mysql-connector-java-5.1.20.jar" />
<connection id="text" driver="text" />
<query connection-id="db1">
SELECT * FROM table;
<query connection-id="db2">
SELECT * FROM table WHERE id = '$id';
<script connection-id="text">
sometext, $rownum
</script>
</query>
</query>
</etl>
The problem is, when the result of the query against db2 is empty the script is not executed.
How to solve this problem?
Regards,
Jacek
You can use count to check the actual number of records. In this case resultset will always return one row. Example:
<query connection-id="db1">
SELECT * FROM table;
<query connection-id="db2">
SELECT count(id) as CNT FROM table WHERE id = ?id;
<!-- The script is executed ONLY IF number of results is zero -->
<script connection-id="text" if="CNT==0">
No matching record for id $id
</script>
</query>
</query>
Probably he doesn't need the if condition, because his problem is the script wasn't executed ;)

Intuit anywhere API telling me that a field is required when it's already specified

I am trying to create an invoice in QB for windows. Here is the XML:
<?xml version='1.0' encoding='utf-8'?>
<Add xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.intuit.com/sb/cdm/v2" xsi:schemaLocation="http://www.intuit.com/sb/cdm/V2./RestDataFilter.xsd " RequestId="1836474224e142c9ad9b7dd6cb0eaa41" FullResponse="true">
<OfferingId>ipp</OfferingId>
<ExternalRealmId>596059545</ExternalRealmId>
<Invoice>
<Header>
<TxnDate>2013-01-30</TxnDate>
<DiscountAmt>0</DiscountAmt>
<ARAccountName>Sales - Support and Maintenance</ARAccountName>
<DiscountAccountName>Discounts/Refunds</DiscountAccountName>
<DueDate>2013-02-17</DueDate>
<Currency>USD</Currency>
<CustomerId>4</CustomerId>
</Header>
<Line>
<Qty>1</Qty>
<UnitPrice>7.00</UnitPrice>
<Desc>Follow-up Test, Instant for Person138-Org3 Person138-Org3</Desc>
</Line>
</Invoice>
</Add>
Here's the response:
-2001: cvc-complex-type.2.4.a: Invalid content was found starting with element 'ARAccountName'. One of '{"http://www.intuit.com/sb/cdm/v2":DiscountAccountId, "http://www.intuit.com/sb/cdm/v2":DiscountAccountName, "http://www.intuit.com/sb/cdm/v2":DiscountTaxable, "http://www.intuit.com/sb/cdm/v2":TxnId}' is expected.
I don't understand, as I already have DiscountAccountName specified. I also tried to go with something more like the create example (same as above but with ARAccountName and DiscountAccountName removed) and got a similar response. Thanks in advance for your help.
The Intuit XML requests are validated by an XSD, and with XML validated by XSDs the order of the tags you provide matters.
That means that if the documentation (https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0600_Object_Reference/Invoice) dictates that ARAccountName comes before DiscountAmt, then you must put ARAccountName before DiscountAmt.
Switch the order of your XML tags to match the order shown in the docs, and you'll be all set.

Trouble getting a YQL table working

So I'm trying to set up a YQL table using the API at http://www.teamliquid.net/video/streams/?filter=live&xml=1 but having some issues.
Here's my table definition:
<?xml version="1.0" encoding="UTF-8"?>
<table xmlns="http://query.yahooapis.com/v1/schema/table.xsd">
<meta>
<author>TL.net</author>
<description>TL.net's streams</description>
<documentationURL>none</documentationURL>
<sampleQuery>select * from {table}</sampleQuery>
</meta>
<bindings>
<select itemPath="streamlist" produces="XML">
<urls>
<url>http://www.teamliquid.net/video/streams/?xml=1</url>
</urls>
<inputs>
<key id="filter" type="xs:string" paramType="query" />
</inputs>
</select>
</bindings>
</table>
Running use "store://q5awkFLmEqteFVOTUJbQ6h" as tl; select * from tl where filter="live" yields the following error:
<?xml version="1.0" encoding="UTF-8"?>
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="0" yahoo:created="2012-02-13T22:14:48Z" yahoo:lang="en-US">
<diagnostics>
<publiclyCallable>true</publiclyCallable>
<url execution-start-time="1" execution-stop-time="33"
execution-time="32" proxy="DEFAULT"><![CDATA[store://q5awkFLmEqteFVOTUJbQ6h]]></url>
<url execution-start-time="35" execution-stop-time="232"
execution-time="197" http-status-code="406"
http-status-message="Not Acceptable" proxy="DEFAULT"><![CDATA[http://www.teamliquid.net/video/streams/?xml=1&filter=live]]></url>
<user-time>232</user-time>
<service-time>258</service-time>
<build-version>25247</build-version>
</diagnostics>
<results/>
</query>
I really can't figure out why it's not working.
In the debug statements, you can see that YQL is reading from your source URL: http://www.teamliquid.net/video/streams/?xml=1&filter=live, but is receiving back an HTTP 406 Not Acceptable error message.
HTTP 406 is meant to cover cases where the server cannot respond in any of the requested (Accept header) formats. I don't know how that applies in this case, but the teamliquid.net source mentions the following:
gzip encoding is required, please also send a valid User-Agent with the name of your application / site and contact info. This page and the XML are updated every five minutes, please do not poll more frequently than every five minutes or you may risk being IP banned. If you have any questions, please PM R1CH.
I suspect it's one of two things:
The YQL servers are not requesting data in gzip or compressed format
The teamliquid.net servers are blocking YQL

Resources