XML Fast And Easy, using SAX - Listener Functions
This document explains how to use XML parsing in lucee.
I have XML as shown below:
//catlog.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
<cd>
<title>Still got the blues</title>
<artist>Gary Moore</artist>
<country>UK</country>
<company>Virgin records</company>
<price>10.20</price>
<year>1990</year>
</cd>
<cd>
<title>Eros</title>
<artist>Eros Ramazzotti</artist>
<country>EU</country>
<company>BMG</company>
<price>9.90</price>
<year>1997</year>
</cd>
<cd>
<title>One night only</title>
<artist>Bee Gees</artist>
<country>UK</country>
<company>Polydor</company>
<price>10.90</price>
<year>1998</year>
</cd>
<cd>
<title>Sylvias Mother</title>
<artist>Dr.Hook</artist>
<country>UK</country>
<company>CBS</company>
<price>8.10</price>
<year>1973</year>
</cd>
<cd>
<title>Maggie May</title>
<artist>Rod Stewart</artist>
<country>UK</country>
<company>Pickwick</company>
<price>8.50</price>
<year>1990</year>
</cd>
<cd>
<title>Romanza</title>
<artist>Andrea Bocelli</artist>
<country>EU</country>
<company>Polydor</company>
<price>10.80</price>
<year>1996</year>
</cd>
<cd>
<title>When a man loves a woman</title>
<artist>Percy Sledge</artist>
<country>USA</country>
<company>Atlantic</company>
<price>8.70</price>
<year>1987</year>
</cd>
<cd>
<title>Black angel</title>
<artist>Savage Rose</artist>
<country>EU</country>
<company>Mega</company>
<price>10.90</price>
<year>1995</year>
</cd>
<cd>
<title>1999 Grammy Nominees</title>
<artist>Many</artist>
<country>USA</country>
<company>Grammy</company>
<price>10.20</price>
<year>1999</year>
</cd>
<cd>
<title>For the good times</title>
<artist>Kenny Rogers</artist>
<country>UK</country>
<company>Mucik Master</company>
<price>8.70</price>
<year>1995</year>
</cd>
<cd>
<title>Big Willie style</title>
<artist>Will Smith</artist>
<country>USA</country>
<company>Columbia</company>
<price>9.90</price>
<year>1997</year>
</cd>
<cd>
<title>Tupelo Honey</title>
<artist>Van Morrison</artist>
<country>UK</country>
<company>Polydor</company>
<price>8.20</price>
<year>1971</year>
</cd>
<cd>
<title>Soulsville</title>
<artist>Jorn Hoel</artist>
<country>Norway</country>
<company>WEA</company>
<price>7.90</price>
<year>1996</year>
</cd>
<cd>
<title>The very best of</title>
<artist>Cat Stevens</artist>
<country>UK</country>
<company>Island</company>
<price>8.90</price>
<year>1990</year>
</cd>
<cd>
<title>Stop</title>
<artist>Sam Brown</artist>
<country>UK</country>
<company>A and M</company>
<price>8.90</price>
<year>1988</year>
</cd>
<cd>
<title>Bridge of Spies</title>
<artist>T`Pau</artist>
<country>UK</country>
<company>Siren</company>
<price>7.90</price>
<year>1987</year>
</cd>
<cd>
<title>Private Dancer</title>
<artist>Tina Turner</artist>
<country>UK</country>
<company>Capitol</company>
<price>8.90</price>
<year>1983</year>
</cd>
<cd>
<title>Midt om natten</title>
<artist>Kim Larsen</artist>
<country>EU</country>
<company>Medley</company>
<price>7.80</price>
<year>1983</year>
</cd>
<cd>
<title>Pavarotti Gala Concert</title>
<artist>Luciano Pavarotti</artist>
<country>UK</country>
<company>DECCA</company>
<price>9.90</price>
<year>1991</year>
</cd>
<cd>
<title>The dock of the bay</title>
<artist>Otis Redding</artist>
<country>USA</country>
<company>Atlantic</company>
<price>7.90</price>
<year>1987</year>
</cd>
<cd>
<title>Picture book</title>
<artist>Simply Red</artist>
<country>EU</country>
<company>Elektra</company>
<price>7.20</price>
<year>1985</year>
</cd>
<cd>
<title>Red</title>
<artist>The Communards</artist>
<country>UK</country>
<company>London</company>
<price>7.80</price>
<year>1987</year>
</cd>
<cd>
<title>Unchain my heart</title>
<artist>Joe Cocker</artist>
<country>USA</country>
<company>EMI</company>
<price>8.20</price>
<year>1987</year>
</cd>
</catalog>
Normally we use DOM(Document Object Model):
<cfscript>
file=GetDirectoryFromPath(GetCurrentTemplatePath())&'catalog.xml';
<span class="nv">dom</span><span class="o">=</span><span class="nf">XMLParse</span><span class="p">(</span><span class="nv">file</span><span class="p">);</span>
<span class="nf">dump</span><span class="p">(</span><span class="nv">dom</span><span class="p">);</span>
<span class="c">// ... extract data needed</span>
</cfscript>
DOM parses the XML to extract the data.
Disadvantages of the DOM model:
Creates an object tree based on complete XML.
- Slow - loads the complete XML in a very complex structure
- Memory Intensive - loads the complete XML in a very complex structure
- Complicated to use
There is a jDOM that is more optimized for Java, and because of that, faster and easier to use. But sadly that project is not maintained any more!!
SAX - Simple API for XML
In Java there is another way to handle the XML called SAX. SAX is an event driver parser. It does not produce the object, but instead you are part of the parsing process.
Advantages
- Fast
- Memory Efficient (only creates persistent objects in memory)
Disadvantage
Complicated to use.
SAX - Listener Functions
You can use SAX on Lucee to define component and listener functions to listen for certain events. The listener functions are as follows:
- startDocument(), is called when it starts to parse the document
- startElement(string name, string attributes)- is called every time it goes into a new tag. This function provides the name of the tag and all attributes.
- body(string content), - is called every time it goes into new tag. This functions provides the content of the body.
- endElement(string name, struct attributes) - is called when you have reached the end of the element.
- endDocument() - is called when you have reached the end of the document.
- error(struct cfcatch) - is called while executing the parser.
Example with SAX:
<cfscript>
file=GetDirectoryFromPath(GetCurrentTemplatePath())&'catalog.xml';
<span class="nv">catalog</span><span class="o">=</span><span class="nv">new</span> <span class="nf">XMLcatalog</span><span class="p">(</span><span class="nv">file</span><span class="p">);</span>
<span class="nf">dump</span><span class="p">(</span><span class="nf">catalog.execute</span><span class="p">());</span>
</cfscript>
XMLcatalog is component,
//XMLcatalog.cfc
component {
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">Start</span> <span class="nv">parsing</span> <span class="nv">an</span> <span class="nv">XML</span> <span class="nv">file.</span>
<span class="o">*</span> <span class="err">@</span><span class="nv">param</span> <span class="nv">xmlFile</span> <span class="nv">XML</span> <span class="nv">file</span> <span class="nv">to</span> <span class="nv">parse</span>
<span class="o">*/</span>
<span class="nv">function</span> <span class="nf">init</span><span class="p">(</span><span class="nv">string</span> <span class="nv">xmlFile</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">variables.xmlFile</span><span class="o">=</span><span class="nv">arguments.xmlFile</span><span class="p">;</span>
<span class="p">}</span>
<span class="nv">function</span> <span class="nf">execute</span><span class="p">()</span> <span class="p">{</span>
<span class="nv">variables.cds</span><span class="o">=</span><span class="p">[];</span>
<span class="nv">variables.cd</span><span class="o">=</span><span class="p">{};</span>
<span class="nv">variables.insideCD</span><span class="o">=</span><span class="nv">false</span><span class="p">;</span>
<span class="nv">variables.currentName</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="k">var</span> <span class="nv">xmlEventParser</span><span class="o">=</span><span class="nf">createObject</span><span class="p">(</span><span class="s2">"java"</span><span class="p">,</span><span class="s2">"lucee.runtime.helpers.XMLEventParser"</span><span class="p">);</span>
<span class="nf">xmlEventParser.init</span><span class="p">(</span>
<span class="nf">getPageContext</span><span class="p">(),</span>
<span class="nv">this.startDocument</span><span class="p">,</span>
<span class="nv">this.startElement</span><span class="p">,</span>
<span class="nv">this.body</span><span class="p">,</span>
<span class="nv">this.endElement</span><span class="p">,</span>
<span class="nv">this.endDocument</span><span class="p">,</span>
<span class="nv">this.error</span>
<span class="p">);</span>
<span class="nf">xmlEventParser.start</span><span class="p">(</span><span class="nv">xmlFile</span><span class="p">);</span>
<span class="nv">return</span> <span class="nv">variables.cds</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">on</span> <span class="nv">to</span> <span class="nv">start</span> <span class="nv">parsing</span> <span class="nv">an</span> <span class="nv">XML</span> <span class="nf">Element</span> <span class="p">(</span><span class="nv">Tag</span><span class="p">).</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">startElement</span><span class="p">(</span><span class="nv">string</span> <span class="nv">uri</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">localName</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">qName</span><span class="p">,</span> <span class="nv">struct</span> <span class="nv">attributes</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nv">qName</span> <span class="o">==</span> <span class="s2">"cd"</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">variables.cd</span><span class="o">=</span><span class="p">{};</span>
<span class="nv">variables.insideCD</span><span class="o">=</span><span class="nv">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nv">variables.insideCD</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">variables.currentName</span><span class="o">=</span><span class="nv">qName</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">call</span> <span class="nv">with</span> <span class="nv">body</span> <span class="nv">of</span> <span class="nv">content</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">body</span><span class="p">(</span><span class="nv">string</span> <span class="nv">content</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="k">len</span><span class="p">(</span><span class="nv">variables.currentName</span><span class="p">))</span> <span class="p">{</span>
<span class="c">//if(len(variables.currentName) && variables.currentName!="price") {</span>
<span class="nv">variables.cd</span><span class="p">[</span><span class="nv">variables.currentName</span><span class="p">]</span><span class="o">=</span><span class="nv">content</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">at</span> <span class="nv">the</span> <span class="nv">end</span> <span class="nv">of</span> <span class="nv">parsing</span> <span class="nv">an</span> <span class="nv">XML</span> <span class="nf">Element</span> <span class="p">(</span><span class="nv">Tag</span><span class="p">).</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">endElement</span><span class="p">(</span><span class="nv">string</span> <span class="nv">uri</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">localName</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">qName</span><span class="p">,</span> <span class="nv">struct</span> <span class="nv">attributes</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nv">qName</span> <span class="o">==</span> <span class="s2">"cd"</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">arrayAppend</span><span class="p">(</span><span class="nv">variables.cds</span><span class="p">,</span><span class="nv">variables.cd</span><span class="p">);</span>
<span class="nv">variables.insideCD</span><span class="o">=</span><span class="nv">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="nv">variables.currentName</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">at</span> <span class="nv">the</span> <span class="nv">start</span> <span class="nv">of</span> <span class="nv">parsing</span> <span class="nv">a</span> <span class="nv">document.</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">startDocument</span><span class="p">()</span> <span class="p">{}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">at</span> <span class="nv">the</span> <span class="nv">end</span> <span class="nv">of</span> <span class="nv">parsing</span> <span class="nv">a</span> <span class="nv">document.</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">endDocument</span><span class="p">()</span> <span class="p">{}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">when</span> <span class="nv">a</span> <span class="nv">error</span> <span class="nv">occurs.</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">error</span><span class="p">(</span><span class="nv">struct</span> <span class="nv">cfcatch</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">echo</span><span class="p">(</span><span class="nv">cfcatch</span><span class="p">);</span>
<span class="p">}</span>
In the XML catalog you can see the listener functions and the listener function passed to the Java object. This helps to parse the data.
var xmlEventParser=createObject("java","lucee.runtime.helpers.XMLEventParser");
xmlEventParser.init(
getPageContext(),
this.startDocument,
this.startElement,
this.body,
this.endElement,
this.endDocument,
this.error
);
xmlEventParser.start(xmlFile);
If we pass an XML string to execute the function, it automatically parses the XML data and returns an array format of parsed data.
You can use the filter on SAX:
Component with filter
//XMLcatalog.cfc
component {
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">Start</span> <span class="nv">parsing</span> <span class="nv">an</span> <span class="nv">XML</span> <span class="nv">file.</span>
<span class="o">*</span> <span class="err">@</span><span class="nv">param</span> <span class="nv">xmlFile</span> <span class="nv">XML</span> <span class="nv">file</span> <span class="nv">to</span> <span class="nv">parse</span>
<span class="o">*/</span>
<span class="nv">function</span> <span class="nf">init</span><span class="p">(</span><span class="nv">string</span> <span class="nv">xmlFile</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">variables.xmlFile</span><span class="o">=</span><span class="nv">arguments.xmlFile</span><span class="p">;</span>
<span class="p">}</span>
<span class="nv">function</span> <span class="nf">execute</span><span class="p">(</span><span class="nv">struct</span> <span class="nv">filter</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">variables.cds</span><span class="o">=</span><span class="p">[];</span>
<span class="nv">variables.cd</span><span class="o">=</span><span class="p">{};</span>
<span class="nv">variables.insideCD</span><span class="o">=</span><span class="nv">false</span><span class="p">;</span>
<span class="nv">variables.currentName</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="nv">variables.removeCD</span><span class="o">=</span><span class="nv">false</span><span class="p">;</span>
<span class="k">var</span> <span class="nv">xmlEventParser</span><span class="o">=</span><span class="nf">createObject</span><span class="p">(</span><span class="s2">"java"</span><span class="p">,</span><span class="s2">"lucee.runtime.helpers.XMLEventParser"</span><span class="p">);</span>
<span class="nv">variables.filter</span><span class="o">=</span><span class="nv">filter</span><span class="p">;</span>
<span class="nf">xmlEventParser.init</span><span class="p">(</span>
<span class="nf">getPageContext</span><span class="p">(),</span>
<span class="nv">this.startDocument</span><span class="p">,</span>
<span class="nv">this.startElement</span><span class="p">,</span>
<span class="nv">this.body</span><span class="p">,</span>
<span class="nv">this.endElement</span><span class="p">,</span>
<span class="nv">this.endDocument</span><span class="p">,</span>
<span class="nv">this.error</span>
<span class="p">);</span>
<span class="nf">xmlEventParser.start</span><span class="p">(</span><span class="nv">xmlFile</span><span class="p">);</span>
<span class="nv">return</span> <span class="nv">variables.cds</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">at</span> <span class="nv">the</span> <span class="nv">start</span> <span class="nv">of</span> <span class="nv">parsing</span> <span class="nv">an</span> <span class="nv">XML</span> <span class="nf">Element</span> <span class="p">(</span><span class="nv">Tag</span><span class="p">).</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">startElement</span><span class="p">(</span><span class="nv">string</span> <span class="nv">uri</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">localName</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">qName</span><span class="p">,</span> <span class="nv">struct</span> <span class="nv">attributes</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nv">qName</span> <span class="o">==</span> <span class="s2">"cd"</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">variables.cd</span><span class="o">=</span><span class="p">{};</span>
<span class="nv">variables.insideCD</span><span class="o">=</span><span class="nv">true</span><span class="p">;</span>
<span class="nv">variables.removeCD</span><span class="o">=</span><span class="nv">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nv">variables.insideCD</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">variables.currentName</span><span class="o">=</span><span class="nv">qName</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">call</span> <span class="nv">with</span> <span class="nv">body</span> <span class="nv">of</span> <span class="nv">content</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">body</span><span class="p">(</span><span class="nv">string</span> <span class="nv">content</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="k">len</span><span class="p">(</span><span class="nv">variables.currentName</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">variables.cd</span><span class="p">[</span><span class="nv">variables.currentName</span><span class="p">]</span><span class="o">=</span><span class="nv">content</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="nf">structKeyExists</span><span class="p">(</span><span class="nv">variables.filter</span><span class="p">,</span><span class="nv">variables.currentName</span><span class="p">)</span> <span class="o">&&</span> <span class="nv">content</span> <span class="o">!=</span> <span class="nv">variables.filter</span><span class="p">[</span><span class="nv">variables.currentName</span><span class="p">])</span> <span class="p">{</span>
<span class="nv">variables.removeCD</span><span class="o">=</span><span class="nv">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">at</span> <span class="nv">the</span> <span class="nv">end</span> <span class="nv">of</span> <span class="nv">parsing</span> <span class="nv">an</span> <span class="nv">XML</span> <span class="nf">Element</span> <span class="p">(</span><span class="nv">Tag</span><span class="p">).</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">endElement</span><span class="p">(</span><span class="nv">string</span> <span class="nv">uri</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">localName</span><span class="p">,</span> <span class="nv">string</span> <span class="nv">qName</span><span class="p">,</span> <span class="nv">struct</span> <span class="nv">attributes</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nv">qName</span> <span class="o">==</span> <span class="s2">"cd"</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">variables.removeCD</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">arrayAppend</span><span class="p">(</span><span class="nv">variables.cds</span><span class="p">,</span><span class="nv">variables.cd</span><span class="p">);</span>
<span class="p">}</span>
<span class="nv">variables.insideCD</span><span class="o">=</span><span class="nv">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="nv">variables.currentName</span><span class="o">=</span><span class="s2">""</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">at</span> <span class="nv">the</span> <span class="nv">start</span> <span class="nv">of</span> <span class="nv">parsing</span> <span class="nv">a</span> <span class="nv">document.</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">startDocument</span><span class="p">()</span> <span class="p">{}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">at</span> <span class="nv">the</span> <span class="nv">end</span> <span class="nv">of</span> <span class="nv">parsing</span> <span class="nv">a</span> <span class="nv">document.</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">endDocument</span><span class="p">()</span> <span class="p">{}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="nv">This</span> <span class="nv">function</span> <span class="nv">will</span> <span class="nv">be</span> <span class="nv">called</span> <span class="nv">when</span> <span class="nv">an</span> <span class="nv">error</span> <span class="nv">occurs.</span>
<span class="o">*/</span>
<span class="nv">public</span> <span class="nv">void</span> <span class="nv">function</span> <span class="nf">error</span><span class="p">(</span><span class="nv">struct</span> <span class="nv">cfcatch</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">echo</span><span class="p">(</span><span class="nv">cfcatch</span><span class="p">);</span>
<span class="p">}</span>
}
You can pass the filter struct when you execute the function.
Example:
<cfscript>
file=GetDirectoryFromPath(GetCurrentTemplatePath())&'catalog.xml';
catalog=new XMLCatalog2(file);
<span class="nf">dump</span><span class="p">(</span><span class="nf">catalog.execute</span><span class="p">({</span><span class="nv">year</span><span class="p">:</span><span class="s2">"1995"</span><span class="p">}));</span>
</cfscript>
The example above executes and returns a result array which contains only the year equal to 1995.
You can modify the component as you like. Instead of storing the array, you can store the result in a database or mail, or whatever you like.
Footnotes
You can see the details in this video: Xml-Fast and Easy