When Klipfolio Dashboard encounters the following in the Klip's <style> block, it understands it as "For each repeating block of XML enclosed in <item>, extract the contents of element <sender> and display it in the first column of the Klip":
item {
type: item;
}
sender {
itemcol: 1;
}
However, not all selectors (tags) are as simple as this.
The following table summarizes all the CSS selectors available in Klipfolio Dashboard. The above is an example of the first selector type listed here:
Table C.1. Supported CSS Selectors
| This CSS selector... | Matches... |
|---|---|
| F | Element <F> |
| E F | F element that has a parent E element |
| E > F | F element that has an immediate parent E element |
| E ~ F | F element that is preceded by an E element |
| E + F | F element that is immediately preceded by an E element |
| E, F | F or E element |
| F::attribute(name) | Attribute name in element <F> |
| F[A="string1"] | F element that has an attribute A with value string1 |
| F:not([A="string1"]) | F element that does not have attribute A with value string1 |
The CSS selector E F finds the first <F> element that has a parent element <E>. The match occurs only if a parent E exists. The parent does not need to be an immediate parent (it could be higher up the tree), as the following example shows.
Notice that the XML to extract data is on the right of the match. You can read these selectors from right to left. For example, E F could be read, "Look for an <F> that has a parent <E>. If a match is found, extract the contents of <F>."
Now let's look at a self-contained Klip that uses this kind of CSS selector.
<klip>
<identity>
<title>
CSS Selector E F
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<x1>
<y1>
<z>
ignore
</z>
</y1>
</x1>
<x>
<y>
<z>
MATCH
</z>
</y>
</x>
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
x z {
itemcol: 1;
}
</style>
</klip>
Here's what the Klip looks like when you run it. The text MATCH is shown because the CSS selector x z found a <z> element with parent <x>.
Notice that this Klip has the XML content source embedded within the <contentsource> tags instead of specifying a URL to the remote content. This works in a Klip, and we wrote the examples this way so you could easily modify the XML and reload the Klip to experiment with the CSS selectors.
Next up is E > F. This CSS selector finds the first <F> element that has an immediate parent element <E>. (Contrast this with the previous E F selector, which doesn't require <E> to be an immediate parent to match <F>.)
Let's do what we did before and start by looking at the example in graphic format:
Now let's look at the detailed code for a Klip that uses this kind of CSS selector.
<klip>
<identity>
<title>
CSS Selector E > F
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<x1>
<y1>
<z>
ignore
</z>
</y1>
</x1>
<x>
<y>
<z>
MATCH
</z>
</y>
</x>
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
y > z {
itemcol: 1;
}
</style>
</klip>
This is what the Klip looks like when you run it.
As before, to test the Klip faster, we embedded specific content in the Klip instead of specifying a URL for <contentsource>.
Now for E ~ F. This CSS selector finds the first <F> element that is preceded by an <E> element at the same level and extracts the value of that <F> element. Matches occur only if an element <E> at the same level exists.
And now for the detailed code for a Klip that uses this kind of CSS selector.
<klip>
<identity>
<title>
CSS Selector E ~ F
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<y>
ignore
</y>
<z>
ignore
</z>
<x>
ignore
</x>
<y>
MATCH
</y>
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
z ~ y {
itemcol: 1;
}
</style>
</klip>
Here's what the Klip looks like when you run it.
You can have more than one ~ in this CSS selector. The figure below shows a CSS selector that is looking for a <z> element that is preceded by two <z> elements at the same level:
Notice there is an <x> tag between two of the <z> tags. The CSS selector ignores the <x> element; it cares only about a string of <z> elements at the same level.
And now for E + F. This CSS selector finds the first <F> element that is immediately preceded by an <E> element at the same level and extracts the value of that <F> element.
Here's the detailed code for a Klip that uses this kind of CSS selector.
<klip>
<identity>
<title>
CSS Selector E + F
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<y>
ignore
</y>
<a>
ignore
</a>
<z>
ignore
</z>
</item>
<item>
<y>
ignore
</y>
<z>
MATCH
</z>
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
y + z {
itemcol: 1;
}
</style>
</klip>
Here's what the Klip looks like when it runs.
You can have more than one + in this CSS selector. For example, the following will look for three <z> elements in a row that are at the same level:
Unlike z ~ z ~ z, which allows other XML elements to appear between the <z> tags, z + z + z requires three <z> tags in a row.
The E, F CSS selector finds an <E> or an <F> element and extracts its value.
Now the detailed code for a Klip that uses this kind of CSS selector.
<klip>
<identity>
<title>
CSS Selector E, F
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<x>
ignore
</x>
<y>
MATCH
</y>
<z>
ignore
</z>
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
y, z {
itemcol: 1;
}
</style>
</klip>And finally the Klip as it appears when it runs.
Now, on to F::attribute(name). This CSS selector extracts the value of the attribute called name from element <F>.
A Klip using the above code would look like this:
Note how only the contents of the attribute day for <x> is extracted, not for <y> even though it has the day attribute as well.
Here is a slightly expanded example of a Klip that uses this kind of CSS selector.
<klip>
<identity>
<title>
CSS Selector F::attribute(name)
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<x day="Tuesday" condition="Sunny" />
<y day="Thursday" condition="Rainy" />
</item>
<item>
<x day="Wednesday" condition="Cloudy" />
<y day="Friday" condition="Sunny" />
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
x::attribute(day) {
itemcol: 1;
}
x::attribute(condition) {
itemcol: 2;
}
</style>
</klip>In the above example, the values for the attribute day (i.e. Tuesday, Wednesday) from <x> element in each repeating block of <item> are extracted to the first column. The second column displays the values of the attribute condition (i.e. Sunny, Partly cloudy).
Here's what the Klip looks like:
Be careful when the XML element itself is the repeating item element, as is the case in the following example:
<klip>
<identity>
<title>
CSS Selector F::attribute(name) 2
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<x day="Tuesday" condition="Sunny" />
<x day="Wednesday" condition="Partly cloudy" />
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
x::attribute(day) {
itemcol: 1;
}
x::attribute(condition) {
itemcol: 2;
}
x {
type: item;
}
</style>
</klip>Notice how element <x> is the repeating item element here and not <item>. Also, the declaration for the item element is placed after the matching patterns. This way, Klipfolio Dashboard will have already found and extracted the values for attributes day and condition by the time it looks for the item element <x>. If the item element declaration were placed before the attributes, however, Klipfolio Dashboard would extract the content of <x> element first, which would be empty, then try to go through the attributes in it, which wouldn't be found.
This CSS selector finds and extracts the value of an <F> element that has an attribute A with value string1.
Here's the detailed code for a Klip that uses this kind of CSS selector.
<klip>
<identity>
<title>
CSS Selector F[A="string1"]
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<x color="blue" size="small">
ignore
</x>
<x color="blue" size="medium">
MATCH
</x>
<x color="blue" size="large">
ignore
</x>
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
x[size="medium"] {
itemcol: 1;
}
</style>
</klip>Here's the Klip as it appears when it runs.
Conversely, selector F:not([A="string1"]) finds and extracts the value of an <F> element that does not have an attribute A with value string1. When you run the following sample code, it is the content of <x size="small"> that is extracted:
For example:
<klip>
<identity>
<title>
CSS Selector F:not([A="string1"])
</title>
</identity>
<locations>
<contentsource>
<![CDATA[
<content>
<item>
<x color="blue" size="small">
MATCH
</x>
<x color="blue" size="medium">
ignore
</x>
</item>
</content>
]]>
</contentsource>
<icon>
http://www.klipfolio.com/static/klips/devguide/builder_icon.png
</icon>
</locations>
<style>
item {
type: item;
}
x:not([size="medium"]) {
itemcol: 1;
}
</style>
</klip>This is what the Klip looks like when you run it.