Gracias por tu visita. Esta página solo está disponible en inglés.

Step 7: Contents Recipe: Query Parameters

Let's continue configuring the Contents recipe by populating the query and queryResultType parameters.

query Parameter

The syntax for JSON feeds differs significantly from the syntax for XML feeds, so the two formats are treated in separate tabs. Note that although the query syntax in this section might seem a little complex, remember that Fire App Builder lets you use any feed structure you want, without limiting you to a specific order or specification. With this flexibility, it's unavoidable that you'll need to use more advanced query syntax to target the elements in your feed.

JSON

In the sample app in Fire App Builder, the value for query is $[?(@.categories[0] in [$$par0$$])]. As with the query parameter in the Categories recipe, this syntax is (mostly) Jayway JsonPath syntax. This syntax uses a Jayway JsonPath filter operator to select the items inside the categories array that have at least one item at the 0 position.

Let's take a step back to unpack this syntax with more clarity, because you'll need to customize this query to fit your own feed syntax. The sample Lightcast feed (which is what the sample Fire App Builder uses) looks like this:

[  
   {  
      "id":"169313",
      "title":"Beautiful Whale Tail Uvita Costa Rica",
      "description":"Beautiful Whale Tail Uvita Costa Rica",
      "duration":"86",
      "thumbURL":"http://le2.cdn01.net/videos/0000169/0169313/thumbs/0169313__007f.jpg",
      "imgURL":"http://le2.cdn01.net/videos/0000169/0169313/thumbs/0169313__007f.jpg",
      "videoURL":"http://edge-vod-media.cdn01.net/encoded/0000169/0169313/video_1880k/T7J66Z106.mp4?source=firetv&channel_id=13454",
      "categories":[  
         "Costa Rica Islands"
      ],
      "channel_id":"13454"
   },
   {  
      "id":"169322",
      "title":"Scuba Diving - Costa Rica",
      "description":"Scuba Diving - Costa Rica (Playa Ocotal & The Bat Islands)",
      "duration":"205",
      "thumbURL":"http://le1.cdn01.net/videos/0000169/0169322/thumbs/0169322__002f.jpg",
      "imgURL":"http://le1.cdn01.net/videos/0000169/0169322/thumbs/0169322__002f.jpg",
      "videoURL":"http://edge-vod-media.cdn01.net/encoded/0000169/0169322/video_1880k/S6IZ6M1QM.mp4?source=firetv&channel_id=13455",
      "categories":[  
         "Costa Rica Underwater"
      ],
      "channel_id":"13455"
   },
   {  
      "id":"169312",
      "title":"San Lucas Trip",
      "description":"Isla San Lucas, Puntarenas, Costa Rica",
      "duration":"192",
      "thumbURL":"http://le1.cdn01.net/videos/0000169/0169312/thumbs/0169312__003f.jpg",
      "imgURL":"http://le1.cdn01.net/videos/0000169/0169312/thumbs/0169312__003f.jpg",
      "videoURL":"http://edge-vod-media.cdn01.net/encoded/0000169/0169312/video_1880k/M0CAAG18G.mp4?source=firetv&channel_id=13454",
      "categories":[  
         "Costa Rica Islands"
      ],
      "channel_id":"13454"
   },
   {  
      "id":"169309",
      "title":"San Jose, Costa Rica",
      "description":"San Jose, Costa Rica",
      "duration":"130",
      "thumbURL":"http://le2.cdn01.net/videos/0000169/0169309/thumbs/0169309__009f.jpg",
      "imgURL":"http://le2.cdn01.net/videos/0000169/0169309/thumbs/0169309__009f.jpg",
      "videoURL":"http://edge-vod-media.cdn01.net/encoded/0000169/0169309/video_1880k/88HFXX0IL.mp4?source=firetv&channel_id=13453",
      "categories":[  
         "Costa Rica Attractions"
      ],
      "channel_id":"13453"
   }
]

(This isn't the full feed, but it shows the repeating structure.)

Plug this feed into the Jayway JsonPath Evaluator. Then run the following query:

$[?(@.categories[0] in ["Costa Rica Islands"])]

This query returns the following:

[
   {
      "id" : "136216",
      "title" : "Falmouth Jamaica Nature's Lullaby ",
      "description" : "Falmouth Jamaica Nature's Lullaby",
      "duration" : "1813",
      "thumbURL" : "http://l4.cdn01.net/_thumbs/0000136/0136216/0136216__001f" type="jpg",
      "imgURL" : "http://l4.cdn01.net/_thumbs/0000136/0136216/0136216__001f" type="jpg",
      "videoURL" : "http://media.cdn01.net/802E1F/process/encoded/video_1880k/0000136/0136216/L2XGJI1LM.mp4?source=firetv&channel_id=13672",
      "categories" : [
         "The Country Jamaica"
      ],
      "channel_id" : "13672"
   }
]

Here's what this query syntax retrieves:

Query Syntax What It Matches
$[ Starts at the root and selects the unnamed array.
?(@.categories[0] in ["The Country Jamaica"])] Creates a filter for all categories arrays that contain ["The Country Jamaica"] in the 0 index position.

Note that there's one difference in query syntax used in the sample Fire App Builder app. Instead of ["The Country Jamaica"], the query parameter uses $$par0$$ instead:

"query": "$[?(@.categories[0] in [$$par0$$])]"

$$par0$$ is a variable defined in Fire App Builder that stores all the items retrieved by the query, and this is where the syntax differs from Jayway JsonPath. In the code, the keyDataType from the categories recipe actually populates the $par0$$ variable in the contents recipe with categories.

Let's go through one more example. Suppose your JSON looks like this:

{
    "titles": {
        "video": [
            {
                "category": "reference",
                "publisher": "Jess",
                "title": "Video title 1",
                "price": 3.95
            },
            {
                "category": "history",
                "publisher": "John",
                "title": "Video title 2",
                "price": 2.99
            },
            {
                "publisher": "Dave",
                "title": "Video title 3",
                "price": 8.99
            },
            {
                "category": "science",
                "publisher": "Jess",
                "title": "Video title 4",
                "price": 3.99
            }
        ]
     }
}

To select all arrays containing science as category, you would use this query:

$.titles.video[?(@.category contains "science")]

This returns:

[
   {
      "category" : "science",
      "publisher" : "Jess",
      "title" : "Video title 4",
      "price" : 3.99
   }
]

However, we need all items in the array that contain category, so we remove the conditions around the @.category:

$.titles.video[?(@.category)]

Now add the in [$$par0$$] variable:

$.titles.video[?(@.category in [$$par0$$])]

Here's a summary of the syntax:

Query Syntax What It Matches
$.titles.video[ Selects the title object and the video array.
?(@.category in [$$par0$$] Filters the array to match on all items that have a category.

Note that when you add in [$$par0$$] in the Jayway JsonPath Evaluator, the Evaluator will not understand this syntax because it's specific to Fire App Builder rather than being part of Jayway JsonPath.

Your query will look different based on your feed and the syntax necessary to match the content objects. For example, here's a more complex query:

$.assets[?(@.type == 'movie.Container' && @.assetId in $$par0$$)]

This query says to start at the root ($), look in the first directory level (.) to the object named assets, and filter the array to type objects that are equal to movie.Container and which contain an assetId element. Jayway JsonPath is powerful — you can use it to target the elements of almost any feed structure.

XML

If your feed is XML, instead of using Jayway JsonPath, you will use XPath expressions to target the specific elements in your feed. XPath reduces your XML document into various items called "nodes." The XPath syntax allows you to target the location of specific nodes.

In the sample MRSS XML app, the value for the query parameter in the contents recipe is as follows:

"query": "//item[./category='$$par0$$']"

Let's take a step back to unpack this syntax with more clarity, because you'll need to customize this query to fit your own feed syntax.

A sample XML feed looks like this:

<rss>
    <channel>
        <item>
            <title>Sample Title 1</title>
            <pubDate>Wed, 26 Oct 2016 20:34:22 PDT</pubDate>
            <link>https://example.com/myshow/episodes/110</link>
            <author>Sample Author name</author>
            <category>Gadgets</category>
        </item>

        <item>
            <title>Sample Title 2</title>
            <pubDate>Mon, 24 Oct 2016 09:24:12 PDT</pubDate>
            <link>https://example.com/myshow/episodes/109</link>
            <author>Sample Author name</author>
            <category>Technology</category>
        </item>
    </channel>
</rss>

With this feed structure, the query for your content recipe would be as follows:

//item[./category='$$par0$$']

Plug this sample XML feed into the XPath Tester. Then run the following query:

//item[./category='Technology']

The result is as follows:

Element='<item>
        <title>Sample Title 2</title>
        <pubDate>Mon, 24 Oct 2016 09:24:12 PDT</pubDate>
        <link>https://example.com/myshow/episodes/109</link>
        <author>Sample Author name</author>
        <category>Technology</category>
        </item>'

Here's what this query syntax retrieves:

Query Syntax What It Matches
//item Match all instances of the item element regardless of its position in the XML structure.
?[./category='Technology'] Selects all categories that are attributes of the item element where the category is equal to Technology.

Note that there’s one difference in query syntax used in the sample Fire App Builder app. Instead of ["Technology"], the query parameter uses $$par0$$ instead:

"query": "//item[./category='$$par0$$']"

$$par0$$ is a variable defined in Fire App Builder that stores all the items retrieved by the query, and this is where the syntax differs from XPath expressions. In the code, the keyDataType from the categories recipe actually populates the $par0$$ variable in the contents recipe with categories.

After you confirm that your query targets a specific category of items in your feed, replace your category (e.g., Technology) with the variable $$par0$$.

Here's a summary of the syntax:

Query Syntax What It Matches
//item Selects all the item elements in the feed.
[./category='$$par0$$'] Filters the selection to match on all items that have a category.

See Querying XML for more details about constructing XPath queries.

Targeting Elements with Namespaces

To target elements with namespaces, such as <media:category> (as the Media RSS specification requires) or <itunes: category text="Apples"/> (as the iTunes RSS tags requires) in the query parameter for Fire App Builder, not all XPath expressions will work. The following two sections provide some guidance.

Media RSS Categories Example

Suppose your XML feed follows the Media RSS spec and looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
   <channel>
      <title>Sample MRSS Feed</title>
      <link>https://some-site.com/mrss.xml</link>
      <language>en-us</language>
      <description>MRSS Feed For Amazon Test</description>
      <atom:link href="https://some-site.com/mrss.xml" rel="self" type="application/rss+xml" />
      <item>
         <title>May 18, 2018 - Apples</title>
         <description>May 18, 2018. Apples are a delicious fruit. Watch this fun documentary about apple growing and making.</description>
         <pubDate>Thu, 31 May 2018 22:45:38 GMT</pubDate>
         <guid>https://some-site.com/apples.mp4</guid>
         <itunes:subtitle>May 18, 2018. Apples are a delicious fruit. Watch this fun documentary about apple growing and making.</itunes:subtitle>
         <media:category>Farming</media:category>
         <media:content url="https://some-site.com/apples.mp4" type="application/mp4" medium="video" duration="2610.688" isDefault="true">
            <media:title>May 18, 2018 - Apples</media:title>
            <media:description>May 18, 2018.  Apples are a delicious fruit. Watch this fun documentary about apple growing and making.</media:description>
            <media:thumbnail url="http://some-site.com/thumbnails/apples.jpg" height="393" width="699" />
         </media:content>
      </item>
      <item>
         <title>May 23, 2018 - Bananas</title>
         <description>May 23, 2018. Bananas are a bunch of fun. Watch this interesting documentary about how to grow bananas.</description>
         <pubDate>Thu, 31 May 2018 22:45:41 GMT</pubDate>
         <guid>https://sample-server..net/3023434001/2345/2335/30349384989301.mpd</guid>
         <itunes:subtitle>May 23, 2018. Bananas are a bunch of fun. Watch this interesting documentary about how to grow bananas..</itunes:subtitle>
         <media:category>Lifestyle</media:category>
         <media:content url="https://some-site.com/bananas.mp4" type="application/mp4" medium="video" duration="2610.688" isDefault="true">
            <media:title>May 18, 2018 - Apples</media:title>
            <media:description>May 18, 2018. Bananas are a bunch of fun. Watch this interesting documentary about how to grow bananas.</media:description>
            <media:thumbnail url="http://some-site.com/thumbnails/bananas.jpg" height="393" width="699" />
         </media:content>
      </item>
   </channel>
</rss>

To target the items in your Contents recipe, you cannot use this:

"query": "//item/media:category/text() in $$par0$$",

Although this will work in XPath Tester, Fire App Builder doesn't use the same XPath parser. Instead, you must use this syntax:

"query": "//item[*[name()='media:category']='$$par0$$']"

This query looks for all nodes with the name item. In those nodes, it use a wildcard to look for the name media:category.

Note that this special syntax restriction with namespaces applies only to the query parameter. The matchList parameter doesn't use XPath expressions.

iTunes RSS Tags Example

Suppose your feed follows the iTunes RSS tags and looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" version="2.0" xml:base="http://www.nasa.gov/">
   <channel>
      <title>Sample 1</title>
      <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt vehicula placerat. Nunc eget auctor leo. Donec vitae neque vehicula, fermentum risus et, scelerisque felis. </description>
      <link>http://www.example.org/</link>
      <itunes:subtitle>Quisque egestas nec metus ac ullamcorper. In a semper ex, vulputate pellentesque massa.</itunes:subtitle>
      <itunes:summary>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt vehicula placerat. Nunc eget auctor leo. Donec vitae neque vehicula, fermentum risus et, scelerisque felis. </itunes:summary>
      <itunes:category text="Fruits" />
      <itunes:keywords>fruit, baskets, farms</itunes:keywords>
      <itunes:image href="https://www.example.org/images/somelogo.png" />
      <item>
         <title>Weekly News, August 11, 2018</title>
         <link>http://www.example.org/weeklynews/august-18-2018.html</link>
         <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt vehicula placerat. Nunc eget auctor leo. Donec vitae neque vehicula, fermentum risus et, scelerisque felis. </description>
         <enclosure url="https://s3-us-west-1.amazonaws.com/devportal-reference-docs/fire-app-builder/media/bunny.mp4" length="44842035" type="video/mp4" />
         <guid isPermaLink="false">august-11-2018</guid>
         <pubDate>Sat, 11 Aug 2018 09:00 EDT</pubDate>
         <source url="http://example.org.rss">Example Video</source>
         <itunes:category text="Apples" />
         <itunes:image href="https://s3-us-west-1.amazonaws.com/devportal-reference-docs/fire-app-builder/media/card.png" />
      </item>     
      <item>
         <title>Weekly News, August 12, 2018</title>
         <link>http://www.example.org/weeklynews/august-18-2018.html</link>
         <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt vehicula placerat. Nunc eget auctor leo. Donec vitae neque vehicula, fermentum risus et, scelerisque felis. </description>
         <enclosure url="https://s3-us-west-1.amazonaws.com/devportal-reference-docs/fire-app-builder/media/bunny.mp4" length="44842333" type="video/mp4" />
         <guid isPermaLink="false">august-12-2018</guid>
         <pubDate>Sat, 12 Aug 2018 09:00 EDT</pubDate>
         <source url="http://example.org.rss">Example Video</source>
         <itunes:category text="Oranges" />
         <itunes:image href="https://s3-us-west-1.amazonaws.com/devportal-reference-docs/fire-app-builder/media/card.png" />
      </item>  
   </channel>
</rss>

Note that with iTunes feeds, there's a general category for the feed (such as <itunes:category text="Fruits">) as well as categories for each item (<itunes:category text="Apples" />). When you target categories for your recipe, you want to target the categories for each item in the feed, not the general feed categories.

To select <itunes:category text="Apples" />, you would use this in your Contents recipe:

"query": "//item[./*[name()='itunes:category'][@text='$$par0$$']]"

This will return more than just the category name. It will return all items that match the parameter:

<item>
   <title>Weekly News, August 11, 2018</title>
   <link>http://www.example.org/weeklynews/august-18-2018.html</link>
   <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt vehicula placerat. Nunc eget auctor leo. Donec vitae neque vehicula, fermentum risus et, scelerisque felis. </description>
   <enclosure length="44842035"
        type="video/mp4"
        url="https://s3-us-west-1.amazonaws.com/devportal-reference-docs/fire-app-builder/media/bunny.mp4"/>
   <guid isPermaLink="false">august-11-2018</guid>
   <pubDate>Sat, 11 Aug 2018 09:00 EDT</pubDate>
   <source url="http://example.org.rss">Example Video</source>
   <itunes:category xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" text="Apples"/>
   <itunes:image xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
           href="https://s3-us-west-1.amazonaws.com/devportal-reference-docs/fire-app-builder/media/card.png"/>
</item>

You can then use the matchList parameters in the recipe (described in the next step) to select the actual attributes. For example, the Categories recipe would look like this:

{
  "cooker": "DynamicParser",
  "format": "xml",
  "model": "com.amazon.android.model.content.Content",
  "translator": "ContentTranslator",
  "modelType": "array",
  "query": "//item[./*[name()='itunes:category'][@text='$$par0$$']]",
  "matchList": [
    "title/#text@mTitle",
    "guid/#text@mId",
    "description/#text@mDescription",
    "enclosure/#attributes/url@mUrl",
    "itunes:image/#attributes/href@mCardImageUrl",
    "itunes:image/#attributes/href@mBackgroundImageUrl"
  ]
}

queryResultType Parameter

Fire App Builder needs to take the result from the query parameter and convert it into a hashmap to process in a Java class. So the next parameter (queryResultType) is used to convert the result into an array of objects. In the sample Fire App Builder application, the value for queryResultType is as follows:

"queryResultType": "[]$",

In this case, the result from the query parameter is a list of strings. This syntax, []$, will convert these strings into a hashmap for processing.

If the result from your query parameter returns a list of strings, include the queryResultType parameter in your Categories recipe and set it equal to []$. If the query's result already an object (a map), omit this parameter altogether.

Next Steps

To finish up with the contents recipe, you need to configure the matchlist and keyDataType parameters. Continue to the next step: Contents Recipe: matchList Parameter.