structKeyExists with XML Data Does Not Work - coldfusion

I am working with the below XML feed and am using structKeyExists and CFLoop to display the data it contains.
<cfoutput>
<cfxml variable="eating">
<catalog>
<results>10 </results>
<food id="bk101">
<initials type="thefirst" name="BK"/>
<initials type="thesecond" name="KB"/>
<keywords>Burger King, pie, hamburgers, fries, milkshakes </keywords>
</food>
<food id="bk102">
<initials type="thefirst" name="TB"/>
<initials type="thesecond" name="BT"/>
<keywords>Taco Bell, tacos, churros, burrito, gorditas </keywords>
</food>
<food id="bk103">
<keywords>Pizza Hut, pizza, cheese, garlic bread </keywords>
</food>
<food id="bk104">
<initials type="thefirst" name="CFA"/>
<initials type="thesecond" name="AFC"/>
<keywords>Chick-Fil-A, chicken, chicken wrap, sauce, Bananas Pudding Milkshake </keywords>
</food>
<food id="bk105">
<initials type="thefirst" name="PE"/>
<initials type="thesecond" name="EP"/>
<keywords>Panda Express, rice, egg rolls, general tso </keywords>
</food>
<food id="bk106">
<initials type="thefirst" name="SJ"/>
<initials type="thesecond" name="JS"/>
<keywords>Sakura Japan, rice, spring rolls, bento </keywords>
</food>
<food id="bk107">
<initials type="thefirst" name="FG"/>
<keywords>Five Guys, fries, burgers, hot dogs </keywords>
</food>
<food id="bk108">
<initials type="thefirst" name="TN"/>
<initials type="thesecond" name="NT"/>
<keywords>Tandoori Nights, biryani, chicken, egg rolls </keywords>
</food>
<food id="bk109">
<initials type="thefirst" name="HoK"/>
<keywords>House of Kabob, rice, bread, beef kabaob, chicken kabob </keywords>
</food>
<food id="bk110">
<initials type="thefirst" name="BF"/>
<initials type="thesecond" name="FB"/>
<keywords>Baja Fresh, quesadilla, soft taco, chili con queso </keywords>
</food>
</catalog>
</cfxml>
</cfoutput>
<cfset data = queryNew("id,initials,initials2,keywords","integer,varchar,varchar,varchar")>
<cfloop index="x" from="1" to="#eating.catalog.results.xmlText#">
<cfif structKeyExists(eating.catalog.food[x],"initials")>
<cfset queryAddRow(data)>
<cfset querySetCell(data,"id",x)>
<cfset querySetCell(data,"initials", eating.catalog.food[x].initials[1].xmlattributes.name )>
<cfset querySetCell(data,"initials2", eating.catalog.food[x].initials[2].xmlattributes.name )>
<cfset querySetCell(data,"keywords", eating.catalog.food[x].keywords )>
</cfif>
</cfloop>
<cfoutput query="data">
#id# - #initials# :: #initials2# :: #keywords# <br /><br />
</cfoutput>
You will notice there is one initial tag missing for Element 3 and two that are missing for Elements 7 and 9 in the XML feed . If the initials tags are added to the XML for Elements 3,7,9, the code works beautifully. However since they are missing, this causes an error to be thrown out an error.
What I would like to do is omit Element 3 (and all other entries which cause an error) from my results and prevent any errors from showing so the application result shows up like so:
1 - BK :: KB :: Burger King, pie, hamburgers, fries, milkshakes
2 - TB :: BT :: Taco Bell, tacos, churros, burrito, gorditas
4 - CFA :: AFC :: Chick-Fil-A, chicken, chicken wrap, sauce, Bananas Pudding Milkshake
5 - PE :: EP :: Panda Express, rice, egg rolls, general tso
6 - SJ :: JS :: Sakura Japan, rice, spring rolls, bento
8 - TN :: NT :: Tandoori Nights, biryani, chicken, egg rolls
10 - BF :: FB :: Baja Fresh, quesadilla, soft taco, chili con queso
Note my example is simplified, in actuality I am working with an XML feed with hundreds of elements. With that in mind, what am I doing wrong and how can I get the above to display correctly?

StructKeyExists() works just fine, but you need to check to ensure the second initials exists too. Adding ArrayLen(eating.catalog.food[x].initials) GT 1 (or EQ 2, if you know it'll always be 2) will solve it.
<cfif structKeyExists(eating.catalog.food[x],"initials") AND ArrayLen(eating.catalog.food[x].initials) GT 1>
With this fix, the example you gave outputs 1, 2, 4, 5, 6, 8, and 10. If you want to print 7 and 9, just move the check to here:
<cfif structKeyExists(eating.catalog.food[x],"initials")>
<cfset queryAddRow(data)>
<cfset querySetCell(data,"id",x)>
<cfset querySetCell(data,"initials", eating.catalog.food[x].initials[1].xmlattributes.name )>
<cfif ArrayLen(eating.catalog.food[x].initials) GT 1>
<cfset querySetCell(data,"initials2", eating.catalog.food[x].initials[2].xmlattributes.name )>
</cfif>
<cfset querySetCell(data,"keywords", eating.catalog.food[x].keywords )>
</cfif>

Related

Revers order of XML dated programs

I was reading through he use of XSLT to reverse the order of this podcast xml file and create a new one in reverse date order. I get the concept but dont understand how to perform this and where to place the xlst code for the reversing of this document.
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>FOOD & WINE with CHEF JAMIE GWEN</title>
<link>http://www.chefjamie.com/</link>
<language>en-us</language>
<copyright>Copyright ©Tastebud Entertainment, Inc. 2018</copyright>
<itunes:subtitle>Delicious conversation every Sunday about food and wine</itunes:subtitle>
<itunes:author>Chef Jamie Gwen</itunes:author>
<atom:link href="http://chefjamie.com/media/podcasts/Food-Wine-Podcasts/ChefJamie_podcast2.xml" rel="self" type="application/rss+xml" />
<webMaster>johnm#splithopsbrewing.com (John Merlino)</webMaster>
<itunes:summary>Syndicated on 70 Plus Stations across the United States and heard live every Sunday!</itunes:summary>
<description>Explore the culinary world with Jamie and meet top chefs, master sommeliers, cookbook authors and artisan food makers. Two hours of delicious conversation weekly !</description>
<itunes:explicit>No</itunes:explicit>
<itunes:image href="http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/chefJamie_PodCast_image.jpg" />
<itunes:name>Chef Jamie Gwen</itunes:name>
<itunes:email>jamie#chefjamie.com</itunes:email>
<itunes:owner>Chef Jamie Gwen</itunes:owner>
<itunes:category text="Arts & Food"/>
<itunes:category text="Arts"/>
<item>
<title>Jan 8th, 2012</title>
<enclosure url="http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-8-12.mp3" length="145178121" type="audio/mp3" />
<guid>http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-8-12.mp3</guid>
<pubDate>Sun, 08 Jan 2012 13:00:00 GMT</pubDate>
<category>Podcasts</category>
<itunes:author>Chef Jamie Gwen</itunes:author>
<itunes:subtitle>Wine, Dine, & Balls</itunes:subtitle>
<itunes:summary>Happy New Year 2012.We are LIVE ON THE RADIO Daniel Holtzman of The Meatball Shop NYC shares melt-in-your mouth recipes for Meatballs of every kind. Sophie Gayot of www dot gayot dot com with highlights on Where to Dine in 2012.Jeff Scott, Author of Notes from a Kitchen with insight into the Culinary World.J. Lohr Winemaker Steve Peck fills our glasses with Cabernet and Pinot Noir</itunes:summary>
<itunes:explicit>No</itunes:explicit>
<itunes:duration>1:15</itunes:duration>
<itunes:keywords>food, cooking, wine, talk, cooking podcast, recipe podcast, diy cooking, learn to cook, learn new recipes, recipes, holiday, Christmas,</itunes:keywords>
</item>
<item>
<title>Jan 15th, 2012</title>
<enclosure url="http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-15-12.mp3" length="47757770" type="audio/mp3" />
<guid>http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-15-12.mp3</guid>
<pubDate>Sun, 15 Jan 2012 13:00:00 GMT</pubDate>
<category>Podcasts</category>
<itunes:author>Chef Jamie Gwen</itunes:author>
<itunes:subtitle>Family, Techniques, and Fitness</itunes:subtitle>
<itunes:summary>New Orleans Chef John Besh shares his Family Table. Editor Jack Bishop of Cooks Illustrated Talks about the Techniques of Home Cooking. Karen Page and Andrew Donenburg discuss their newest book on Food and Wine. Fitness Expert Lisa Lynn creates your Workout Strategy for 2012 </itunes:summary>
<itunes:explicit>No</itunes:explicit>
<itunes:duration>49:45</itunes:duration>
<itunes:keywords>food, cooking, wine, talk, cooking podcast, recipe podcast, diy cooking, learn to cook, learn new recipes, recipes, holiday, christmas,</itunes:keywords>
</item>
<item>
<title>Jan 22nd, 2012</title>
<enclosure url="http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-22-12.mp3" length="18924125" type="audio/mp3" />
<guid>http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-22-12.mp3</guid>
<pubDate>Sun, 22 Jan 2012 13:00:00 GMT</pubDate>
<category>Podcasts</category>
<itunes:author>Chef Jamie Gwen</itunes:author>
<itunes:subtitle>Produce, Asian Meals, and Ground Meat</itunes:subtitle>
<itunes:summary>Jamie and Lana Review the Top 10 Best Finds at The Fancy Food Show. Southern Chef Hugh Acheson on Seasonal Produce. Paul Martins American Grill Partner Brian Bennett shares his commitment to Local, Sustainable and Organic. Author Nina Simonds celebrates Chinese New Year with her "Simple Asian Meals". GM and Master Sommelier Michael Jordan LIVE from The Ranch! Jim Villas highlights the best recipes using Ground Meat for Superbowl! From his new cookbook "From The Ground Up" </itunes:summary>
<itunes:explicit>No</itunes:explicit>
<itunes:duration>01:18:51</itunes:duration>
<itunes:keywords>food, cooking, wine, talk, cooking podcast, recipe podcast, diy cooking, learn to cook, learn new recipes, recipes, holiday, Christmas,</itunes:keywords>
</item>
<item>
<title>Jan 29th, 2012</title>
<enclosure url="http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-29-12.mp3" length="161118248" type="audio/mp3" />
<guid>http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/1-29-12.mp3</guid>
<pubDate>Sun, 29 Jan 2012 13:00:00 GMT</pubDate>
<category>Podcasts</category>
<itunes:author>Chef Jamie Gwen</itunes:author>
<itunes:subtitle>Superbowl of Food, Salmon, Spices, and BBQ</itunes:subtitle>
<itunes:summary>Gridiron Grub: Lana and Jamie dish on the Superbowl of Food. Jeff Hall of Chapter One in Santa Ana highlights the Newest Artisan Spirits On The Market. Fish Farmer Stewart Hawthorne of Skuna Bay Salmon on Craft Raised Salmon. Chef Mark Garcia pumps of the Flavor of our dishes with the Flavor Forecast 2012 from McCormick Spices. Rick Browne,the King of BBQ, Smokes Us Out! </itunes:summary>
<itunes:explicit>No</itunes:explicit>
<itunes:duration>01:23:55</itunes:duration>
<itunes:keywords>food, cooking, Superbowl, talk, cooking podcast, recipe podcast, diy cooking, learn to cook, learn new recipes, recipes, bbq, spices</itunes:keywords>
</item>
<item>
<title>Feb 5th, 2012</title>
<enclosure url="http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/2-5-12.mp3" length="80225176" type="audio/mp3" />
<guid>http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/2-5-12.mp3</guid>
<pubDate>Sun, 05 Feb 2012 13:00:00 GMT</pubDate>
<category>Podcasts</category>
<itunes:author>Chef Jamie Gwen</itunes:author>
<itunes:subtitle>Superbowl Sunday Show</itunes:subtitle>
<itunes:summary>Ideas and Recipes for a Winning Superbowl Party Beer Truffles. Were having a party with PJ Clarkes Chef Johnny Church He is dishing on burger blends, oysters and the best fries. Arizona Biltmores Exec Chef Todd Sicolo on Wrights Restaurant and Big Game Food. Southern Chef Hugh Acheson shares his Modern Southern Style. Rick Rodgers with Sparkling Cocktail Inspiration </itunes:summary>
<itunes:explicit>No</itunes:explicit>
<itunes:duration>01:23:34</itunes:duration>
<itunes:keywords>food,cooking,superbowl,talk,cooking podcast,recipe podcast,diycooking,beer,truffles,superbowl</itunes:keywords>
</item>
<item>
<title>Feb 12th, 2012</title>
<enclosure url="http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/2-12-12.mp3" length="81886563" type="audio/mp3" />
<guid>http://www.chefjamie.com/media/podcasts/Food-Wine-Podcasts/2-12-12.mp3</guid>
<pubDate>Sun, 12 Feb 2012 13:00:00 GMT</pubDate>
<category>Podcasts</category>
<itunes:author>Chef Jamie Gwen</itunes:author>
<itunes:subtitle>The Love Show</itunes:subtitle>
<itunes:summary>Spago Pastry Chef Sherry Yard gets us in the mood for love with Valentines Day Desserts. Chef Bernard Guillas of the Marine Room shares Recipes for Romance. Tanya Zuckerbrot Registered Dietitian and the creator of The F-Factor Diet divulges the Foods that you can Add To Your Diet to Lose Weight. Bake, Decorate, Celebrate! Wilton Baking Schools Nancy Siler gives us sweet Valentine Inspiration </itunes:summary>
<itunes:explicit>No</itunes:explicit>
<itunes:duration>01:25:18</itunes:duration>
<itunes:keywords>food, cooking, superbowl, talk, cooking podcast, recipe podcast, diy cooking, learn to cook, learn new recipes, recipes, sherry yard, romance, love</itunes:keywords>
</item>
</channel>
</rss>
Would like to take the programs and list them on another fresh xml document that can be hit showing the most recent show first.
If the items are already arranged in chronological order from oldest to newest, and you merely want to reverse the existing order, you can do:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="channel">
<xsl:copy>
<xsl:apply-templates select="*[not(self::item)]"/>
<xsl:apply-templates select="item">
<xsl:sort select="position()" data-type="number" order="descending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Cfloop inside cfloop? [duplicate]

This question already has an answer here:
Why my cfloop stop after inserting first id?
(1 answer)
Closed 7 years ago.
I have a question about my cfloop inside of another cfloop. Here is my code:
<cfloop from="1" to="5" index="k">
<cfloop from="#qry.S#" to="#qry.E#" index="i" step="#CreateTimeSpan(0,0,qry.Leng,0)#">
<cfset TimeEnd = dateAdd("n", Leng, i)>
<tr>
<td>(#k#) #timeFormat(TimeStart, "hh:mm tt")# - #timeFormat(TimeEnd, "hh:mm tt")#</td>
</tr>
<cfset TimeStart = dateAdd("n", qry.Leng, i)>
</cfloop>
</cfloop>
This code above gives me output like this:
09:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
As you can see I put the star next to the line where my code gives me wrong values. For some reason my start time after first loop is done once, starts from the end time. Can anyone tell me how this can be fixed?
You can't use "i" as the index for both the outer and inner loop. Use something else for the inner loop (x). For example:
<cfloop from="1" to="5" index="i">
<cfloop from="#qry.S#" to="#qry.E#" index="x" step="#CreateTimeSpan(0,0,qry.Leng,0)#">
<cfset TimeEnd = dateAdd("n", Leng, i)>
<tr>
<td> #timeFormat(TimeStart, "hh:mm tt")# - #timeFormat(TimeEnd, "hh:mm tt")#</td>
</tr>
<cfset TimeStart = dateAdd("n", qry.Leng, i)>
</cfloop>
</cfloop>
I'm not sure of the intention here so you may need to swap some of you i's for x's in the inner loop depending on what you are after (start-end for example).
*************************** edits ****************
Maybe I see your issue (not sure) but based on your comment your issue is going to be that you have reset the timestart var. You need to do that after your first loop begins.
<cfloop> outer loop
<Cfset timestart = *starting value*>
<cfloop> inner looop
Other wise your timestart is going to be whatever your last cfset for it was - in the inner loop.

Solr query not working for inputs with spaces though the output from analysis phase seems fine for it to work

I'm stuck up with an issue as elaborated here. I have a text field that stores bed and bath info into it, while indexing I store values like 2b 3bt for 2 beds and 3 baths respectively.
Finally I need to support queries like "2 beds 3 baths" , "beds 2 3 baths", "2 bed rooms 3 baths", "2bd 3bth" ....
For attaining this, I use a text field with the text_general type as below
<field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(?i)((\d\.?\d{0,2})\s*(bed\s*rooms|bed\s*room|beds|bed|bdr|bd|br|b)|(bed\s*rooms|bed\s+room|beds|bed|bdr|bd|br|b)\s*(\d\.?\d{0,2}))" replacement="$2$5b" />
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(?i)((\d\.?\d{0,2})\s*(bath\s*rooms|bath\s*room|baths|bath|bth|bt|bh|ba)|(bath\s*rooms|bath\s*room|baths|bath|bth|bt|bh|ba)\s*(\d\.?\d{0,2}))" replacement="$2$5bt" />
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.TrimFilterFactory" updateOffsets="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
I tried Solr queries with the admin interface and it is almost working fine for all combinations except for case with intermediate spaces like "6 beds 6 baths" or "6 bed room 6 bath room" at the same time "6beds 6baths" gets me correct results. Here is the url with the parameters that I put across to solr for this query
/solr/select?q=6b+6ba&wt=xml&indent=true&q.op=AND
I checked the Solr admin analysis interface for each of these case and found no difference at all. As the analysis phase is producing the same results I was expecting both these queries to work similar. Can any one direct me, why these two queries are not behaving in a similar manner ?
This is what I see at the solr admin analysis interface for the two queries in question
For input : 6 beds 6 bath room,
PRCF 6b 6bath room
PRCF 6b 6bt
ST 6b | 6bt
TF 6b | 6bt
SF 6b | 6bt
LCF 6b | 6bt
For input : 6b 6bt
PRCF 6b 6bt
PRCF 6b 6bt
ST 6b | 6bt
TF 6b | 6bt
SF 6b | 6bt
LCF 6b | 6bt
Sample inputs & outputs -
Here are some sample inputs that I tried using the field definition I already mentioned above,
Note: (#) is just the serial number and is not part of the input
(1) 2beds 3baths Fresno
(2) 3baths 2beds Fresno
(3) Fresno 2bedroom 3bathroom
(4) beds2 3baths Fresno
(5) beds2 bathrooms3 Fresno
All the above are working fine even now, Here are some inputs that are still a concern for me with the current field definition
(6) 2 beds 3 baths Fresno
(7) 2 bed rooms 3 baths Fresno
(8) Fresno 2 bed room 3 baths
(9) Fresno 3baths 2 bed rooms
The output that I expect for the above inputs after analysis phase in the same serial number order is as below (as while indexing for 2beds 3 baths, I index the data as 2b 3bt),
(1) 2b 3bt Fresno
(2) 3bt 2b Fresno
(3) Fresno 2b 3bt
(4) 2b 3bt Fresno
(5) 2b 3bt Fresno
(6) 2b 3bt Fresno
(7) 2b 3bt Fresno
(8) Fresno 2b 3bt
(9) Fresno 3bt 2b
But up to this point I think I'm doing fine as I can generate the exact same output on analysis which I confirmed through the Solr admin Analysis interface, The real issue here is that I can get the query to fetch correct search results for the first section of the input (ie) up to #5 but for the inputs from #6 to #9 I don't get any results
This is a sample query format that I try for input #1 ie) 2beds 3baths Fresno
/solr/collection1/select?q=2beds+3baths+Fresno&wt=xml&indent=true&q.op=AND
And this one for #6, ie) 2 beds 3 baths Fresno
/solr/collection1/select?q=2+beds+3+baths+Atlanta&wt=xml&indent=true&q.op=AND
The final solution that I applied here is as below,
I removed the PatternReplaceCharFilterFactory for bed and bath from the Query time Analyser and did a similar pattern replacement on the input text from my servlet.
So now for the following input text
2 beds 3 baths Fresno
From my servlet code, I convert it to
2b 3bt Fresno
This is what I then pass on to solr to work on ... and it is now working fine
Here is the modified fieldtype definition for the text_general field,
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.TrimFilterFactory" updateOffsets="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>

Error with CFLoop When Entries Are Missing [duplicate]

This question already has answers here:
CFLoop Error For Missing Entries
(2 answers)
Closed 8 years ago.
I have the following code.
<cfoutput>
<cfxml variable="eating">
<catalog>
<results>10</results>
<food id="bk101">
<initials>BK</initials>
<keywords>Burger King, pie, hamburgers, fries, milkshakes</keywords>
</food>
<food id="bk102">
<initials>TB</initials>
<keywords>Taco Bell, tacos, churros, burrito, gorditas</keywords>
</food>
<food id="bk103">
<keywords>Pizza Hut, pizza, cheese, garlic bread</keywords>
</food>
<food id="bk104">
<initials>CFA</initials>
<keywords>Chick-Fil-A, chicken, chicken wrap, sauce, Bananas Pudding Milkshake</keywords>
</food>
<food id="bk105">
<initials>PE</initials>
<keywords>Panda Express, rice, egg rolls, general tso</keywords>
</food>
<food id="bk106">
<initials>SJ</initials>
<keywords>Sakura Japan, rice, spring rolls, bento</keywords>
</food>
<food id="bk107">
<keywords>Five Guys, fries, burgers, hot dogs</keywords>
</food>
<food id="bk108">
<initials>TN</initials>
<keywords>Tandoori Nights, biryani, chicken, egg rolls</keywords>
</food>
<food id="bk109">
<initials>HoK</initials>
<keywords>House of Kabob, rice, bread, beef kabaob, chicken kabob</keywords>
</food>
<food id="bk110">
<initials>BF</initials>
<keywords>Baja Fresh, quesadilla, soft taco, chili con queso</keywords>
</food>
</catalog>
</cfxml>
<cfset data = queryNew("id,initials,keywords","integer,varchar,varchar")>
<cfloop index="x" from="1" to="#eating.catalog.results.xmlText#">
<cfset queryAddRow(data)>
<cfset querySetCell(data,"id",x)>
<cfset querySetCell(data,"initials","#eating.catalog.food[x].initials#")>
<cfset querySetCell(data,"keywords","#eating.catalog.food[x].keywords#")>
</cfloop>
</cfoutput>
<cfoutput query="data">
#id# - <b>#initials#</b> #keywords#<br />
</cfoutput>
You will notice the initial tags are missing for Elements 3 and 7 in the XML feed . If the initials tags are added to the XML for Elements 3 and 7, the code works beautifully. However since they are missing, this causes CFLoop to throw out an error.
What I would like to do is omit Element 3 (and all other entries which cause an error) from my results and prevent any errors from showing so the application result shows up like so
1 - BK Burger King, pie, hamburgers, fries, milkshakes
2 - TB Taco Bell, tacos, churros, burrito, gorditas
4 - CFA Chick-Fil-A, chicken, chicken wrap, sauce, Bananas Pudding Milkshake
5 - PE Panda Express, rice, egg rolls, general tso
6 - SJ Sakura Japan, rice, spring rolls, bento
8 - TN Tandoori Nights, biryani, chicken, egg rolls
9 - HoK House of Kabob, rice, bread, beef kabaob, chicken kabob
10 - BF Baja Fresh, quesadilla, soft taco, chili con queso
The above feed is a simplified example, my actual feed has hundreds of elements. With that in mind, how can I omit any Elements that give me an error, while still including the elements that do?
Mike, I copied all your code into a local script to run a quick test. I made the one minor edit to your CFLOOP code and was about to get the output with no errors (added a conditional evaluating the struct to ensure that the key exists with structKeyExists):
<cfloop index="x" from="1" to="#eating.catalog.results.xmlText#">
<cfif structKeyExists(eating.catalog.food[x],"initials")>
<cfset queryAddRow(data)>
<cfset querySetCell(data,"id",x)>
<cfset querySetCell(data,"initials", eating.catalog.food[x].initials )>
<cfset querySetCell(data,"keywords", eating.catalog.food[x].keywords )>
</cfif>
</cfloop>
Here is the output I received in my browser:
1 - BK Burger King, pie, hamburgers, fries, milkshakes
2 - TB Taco Bell, tacos, churros, burrito, gorditas
4 - CFA Chick-Fil-A, chicken, chicken wrap, sauce, Bananas Pudding Milkshake
5 - PE Panda Express, rice, egg rolls, general tso
6 - SJ Sakura Japan, rice, spring rolls, bento
8 - TN Tandoori Nights, biryani, chicken, egg rolls
9 - HoK House of Kabob, rice, bread, beef kabaob, chicken kabob
10 - BF Baja Fresh, quesadilla, soft taco, chili con queso

How to transform data with XSLT

I am really new to XSLT but I was wondering if I could use it to solve a problem.
I would like to transform data like this:
<thing id=1>
<value>T</value>
<dateTime>1/11/2011 09:30 PM</dateTime>
</thing>
<thing id=1>
<value>F</value>
<dateTime>1/11/2011 09:32 PM</dateTime>
</thing>
<thing id=2>
<value>T</value>
<dateTime>1/11/2011 09:35 PM</dateTime>
</thing>
<thing id=1>
<value>T</value>
<dateTime>1/11/2011 09:37 PM</dateTime>
</thing>
<thing id=2>
<value>F</value>
<dateTime>1/11/2011 09:40 PM</dateTime>
</thing>
<thing id=1>
<value>F</value>
<dateTime>1/11/2011 09:45 PM</dateTime>
</thing>
Into a table like this:
Thing 1
T F Duration
1/11/2011 09:30 PM 1/11/2011 09:32 PM 02:00
1/11/2011 09:37 PM 1/11/2011 09:45 PM 08:00
Thing 2
T F Duration
1/11/2011 09:35 PM 1/11/2011 09:40 PM 05:00
Also, in my above example, I am presuming I have matching (i.e paired) T and F values. If one were actually missing, I would want it to display null or nothing.
So, with that in mind, is it possible to use xslt? If so, how would I do it?
Thanks,
John
You need to decide whether to use XSLT 1.0 or 2.0 here. Your problem involves grouping, and grouping is much easier in XSLT 2.0 - but not all environments yet support XSLT 2.0.
I don't think it's worth trying to suggest any code until you have made this decision.