I've spent a couple of hours faffing with this and I've had a root around the forum but I must be missing something obvious.
I had a macro that called an external URL for an API, got back some XML and iterated through the results. (well, I actually called a custom extension which called the URL for me and returned XML)
All was fine, until I realised high traffic site = many API calls. So FeedCache2 to the rescue. Great. :)
Now the XML is in a file stored locally (App_Data/FeedCache/myfilename.xml). My macro can load the XML. Then filter the events by their 'start date' - so I can display events past, future or all events.
The problem?
If I "count" the number of event nodes, it works and I get '2' back. Great! But when I try to foreach iterate through them using the same syntax, it fails.
<!-- File location --> <xsl:variable name="fileLocation" select="'C:\inetpub\wwwroot\App_Data\FeedCache\AllEvents2.xml'"/> <!-- Get cached data --> <xsl:variable name="FileXml" select="umbraco.library:GetXmlDocument($fileLocation, 'false')" /> <!-- Get the correct nodes based on if we're only meant to be showing all, previous or future events --> <xsl:variable name="EventXml"> <xsl:choose> <xsl:when test="/macro/showEvents != '' and /macro/showEvents = 'future'"> <xsl:copy-of select="$FileXml//events [umbraco.library:DateGreaterThanOrEqualToday(event/start_date)]"/> </xsl:when> <xsl:when test="/macro/showEvents != '' and /macro/showEvents = 'past'"> <xsl:copy-of select="$FileXml//events [umbraco.library:DateDiff(umbraco.library:CurrentDate(), event/start_date, 's') > 0]"/> </xsl:when> <xsl:otherwise> <xsl:copy-of select="$FileXml//events"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:value-of select="count(ucomponents.xml:Parse($EventXml)/*)"/>
Filtering the events by date works fine and the content of $EventXml is correct. The 'count' statement above displays "2" - as there are two <event> nodes.
Error parsing the XSLT: System.OverflowException: Value was either too large or too small for an Int32. at System.Convert.ToInt32(Double value) at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType) at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args) at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer) at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) at umbraco.macro.GetXsltTransformResult(XmlDocument macroXML, XslCompiledTransform xslt, Dictionary`2 parameters) at umbraco.presentation.umbraco.developer.Xslt.xsltVisualize.visualizeDo_Click(Object sender, EventArgs e)
I've tried masses of syntaxes. I can only think that the foreach fails because there is no 'root' node in the results after I get the Events I want (by date). As the XML will look like this:
You should use the node-set() extension function to convert the $EventXml variable back into an XPath-navigable variable, not the Parse() function (which just converts a string of XML into actual XML nodes):
<xsl:for-each select="msxml:node-set($EventXml)">
<!-- Do stuff with <event> nodes -->
</xsl:for-each>
Not sure about the error, though - usually that's due to a call to GetMedia() or NiceUrl() without an id...
Also the error disappeared when I switched over the node-set, I can only assume that calling Parse meant that the XSLT parser assumed one of the values used could potentially be invalid/null.
Parsing XML from local document
I've spent a couple of hours faffing with this and I've had a root around the forum but I must be missing something obvious.
I had a macro that called an external URL for an API, got back some XML and iterated through the results.
(well, I actually called a custom extension which called the URL for me and returned XML)
Example:
Example of XML returned (simplified):
All was fine, until I realised high traffic site = many API calls.
So FeedCache2 to the rescue. Great. :)
Now the XML is in a file stored locally (App_Data/FeedCache/myfilename.xml).
My macro can load the XML. Then filter the events by their 'start date' - so I can display events past, future or all events.
The problem?
If I "count" the number of event nodes, it works and I get '2' back. Great!
But when I try to foreach iterate through them using the same syntax, it fails.
Filtering the events by date works fine and the content of $EventXml is correct.
The 'count' statement above displays "2" - as there are two <event> nodes.
But this next line fails:
<xsl:for-each select="ucomponents.xml:Parse($EventXml)/*">
Like so:
I've tried masses of syntaxes. I can only think that the foreach fails because there is no 'root' node in the results after I get the Events I want (by date).
As the XML will look like this:
Hi Drew,
You should use the node-set() extension function to convert the $EventXml variable back into an XPath-navigable variable, not the Parse() function (which just converts a string of XML into actual XML nodes):
Not sure about the error, though - usually that's due to a call to GetMedia() or NiceUrl() without an id...
/Chriztian
Node-set works great.
Also the error disappeared when I switched over the node-set, I can only assume that calling Parse meant that the XSLT parser assumed one of the values used could potentially be invalid/null.
Cheers!
is working on a reply...