|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
XSL - The variable or parameter '...' is either not defined or it is out of scope.System.Xml.Xsl.XslLoadException: The variable or parameter 'lastrecordwaskit' was duplicated within the same scope. An error occurred at (174,12). at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver) at System.Xml.Xsl.XslCompiledTransform.Load(XmlReader stylesheet) at MyProject.MyClass.TranslateXML(String xsltFileName, String xmlText) in C:\Source\MySolution\MyProject\MyClass.vb:line 155 I have included the XSL code below which is related to the issue. In order to maintain the previous value of "iskit", I am declaring a variable "lastrecordwaskit" at the end of the loop. Near the beginning of the loop, prior to the variable declaration of "lastrecordwaskit", I am checking for "position() > 1" before trying to access "lastrecordwaskit". In .NET 1.1, this would allow the "lastrecordwaskit" variable to be declared prior to it being accessed. In .NET 2.0, it appears that this will no longer work. I need to be able to access the previous value of a variable (or previous XML element) while inside of a loop. Are there any solutions to this problem with .NET 2.0? Thanks, Jody <xsl:for-each select="Order/Invoice/InvoiceDetails/InvoiceDetail"> <xsl:variable name="iskit"> <xsl:choose> <xsl:when test="@idt_set_master='N' and @idt_set_component_seq>0"> 1 </xsl:when> <xsl:otherwise> 0 </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:if test="position()>1"> <xsl:if test="$lastrecordwaskit=1 and $iskit=0"> <tr> <td> </td> </tr> </xsl:if> </xsl:if> {Additional Code ...} <xsl:variable name="lastrecordwaskit"><xsl:value-of select="$iskit"/></xsl:variable> </xsl:for-each> Jody Gelowitz wrote:
Show quote > <xsl:for-each select="Order/Invoice/InvoiceDetails/InvoiceDetail"> That variable is not in scope for the above xsl:if as it is a sibling > > <xsl:variable name="iskit"> > > <xsl:choose> > > <xsl:when test="@idt_set_master='N' and > @idt_set_component_seq>0"> > > 1 > > </xsl:when> > > <xsl:otherwise> > > 0 > > </xsl:otherwise> > > </xsl:choose> > > </xsl:variable> > > <xsl:if test="position()>1"> > > <xsl:if test="$lastrecordwaskit=1 and $iskit=0"> > > <tr> > > <td> </td> > > </tr> > > </xsl:if> > > </xsl:if> > > {Additional Code ...} > > <xsl:variable name="lastrecordwaskit"> node of the xsl:if but would need to be defined in an ancestor of the xsl:if to be in scope. I managed to get this working by changing the XslCompiledTransform object to
the old XslTransform object. For thoroughness, do you have an example of where the variable should be declared? Currently, I have: For Each Declare "iskit" If position > 1 If "lastrecordwaskit" Then ... End If End If ... Declare "lastrecordwaskit" = "iskit" Next I get a duplicate declaration error if I try to declare "lastrecordwaskit" outside of the For...Each loop. Thanks, Jody Show quote "Martin Honnen" <mahotr***@yahoo.de> wrote in message news:%23SjVrtOeGHA.536@TK2MSFTNGP02.phx.gbl... > > > Jody Gelowitz wrote: > > >> <xsl:for-each select="Order/Invoice/InvoiceDetails/InvoiceDetail"> >> >> <xsl:variable name="iskit"> >> >> <xsl:choose> >> >> <xsl:when test="@idt_set_master='N' and >> @idt_set_component_seq>0"> >> >> 1 >> >> </xsl:when> >> >> <xsl:otherwise> >> >> 0 >> >> </xsl:otherwise> >> >> </xsl:choose> >> >> </xsl:variable> >> >> <xsl:if test="position()>1"> >> >> <xsl:if test="$lastrecordwaskit=1 and $iskit=0"> >> >> <tr> >> >> <td> </td> >> >> </tr> >> >> </xsl:if> >> >> </xsl:if> >> >> {Additional Code ...} >> >> <xsl:variable name="lastrecordwaskit"> > > That variable is not in scope for the above xsl:if as it is a sibling node > of the xsl:if but would need to be defined in an ancestor of the xsl:if to > be in scope. > > -- > > Martin Honnen --- MVP XML > http://JavaScript.FAQTs.com/ Jody Gelowitz wrote:
> For thoroughness, do you have an example of XSLT is not a procedural language, it is declarative and template based > where the variable should be declared? Currently, I have: > > For Each > Declare "iskit" > If position > 1 > If "lastrecordwaskit" Then > ... > End If > End If > ... > Declare "lastrecordwaskit" = "iskit" > Next so I don't think your attempts to write XSLT with VB pseudo code are helpful to understand XSLT or to solve the problem. I can't tell from the above what you are trying to achieve, how your XML input looks so it is not possible to suggest an XSLT solution. You might need a template taking parameters where you pass in the parameter as needed and call the template again as needed. Or it might suffice to look at the preceding sibling element and its attributes, not needing a parameter or variable at all. By using the XslTransform object (TranslateXML function), I was able to get this working in .NET 2.0. TranslateXML20 is the function that did not work with using XslCompiledTransform. I have attached the code for both versions.
Jody Private Function TranslateXML(ByVal xsltFileName As String, ByVal xmlText As String) As String Dim xst As System.Xml.Xsl.XslTransform = Nothing Dim xal As System.Xml.Xsl.XsltArgumentList = Nothing Dim xtr As System.Xml.XmlTextReader = Nothing Dim resolver As System.Xml.XmlUrlResolver = Nothing Dim xsltExt As XSLTExtension = Nothing Dim xtrIn As System.Xml.XmlTextReader = Nothing Dim xpd As System.Xml.XPath.XPathDocument Dim sw As StringWriterWithEncoding = Nothing Dim strReturn As String = String.Empty Try 'Setup the XSL Transform object xtr = New System.Xml.XmlTextReader(xmlText, Xml.XmlNodeType.Document, Nothing) xst = New System.Xml.Xsl.XslTransform xst.Load(xsltFileName) 'Prepare the XML document to be transformed xtrIn = New System.Xml.XmlTextReader(xmlText, Xml.XmlNodeType.Document, Nothing) xpd = New System.Xml.XPath.XPathDocument(xtrIn) 'Prepare the output objects 'This prevents unprintable characters from being printed at the top of the resulting string sw = New StringWriterWithEncoding(New System.Text.UTF8Encoding(False)) 'Transform the XML document using the XSLT file and place the output in "sw" resolver = New System.Xml.XmlUrlResolver xal = New System.Xml.Xsl.XsltArgumentList xsltExt = New XSLTExtension xal.AddExtensionObject("urn:date-format", xsltExt) xst.Transform(xpd, xal, sw, resolver) strReturn = sw.ToString.Replace(" ", " ") 'Replace the   character with Catch ex As Exception Dim strMessage As String strMessage = "xsltFileName: " & xsltFileName & ControlChars.CrLf strMessage &= "xmlText: " & ControlChars.CrLf & xmlText & ControlChars.CrLf RaiseEvent Exception(Me, New EMailExceptionEventArgs(ex)) Finally If Not xal Is Nothing Then xal = Nothing End If If Not sw Is Nothing Then sw.Close() sw = Nothing End If If Not xtrIn Is Nothing Then xtrIn.Close() xtrIn = Nothing End If If Not xtr Is Nothing Then xtr.Close() xtr = Nothing End If End Try Return strReturn End Function Private Function TranslateXML20(ByVal xsltFileName As String, ByVal xmlText As String) As String Dim xst As System.Xml.Xsl.XslCompiledTransform = Nothing Dim xtrXSLT As System.Xml.XmlTextReader = Nothing Dim xal As System.Xml.Xsl.XsltArgumentList = Nothing Dim resolver As System.Xml.XmlUrlResolver = Nothing Dim xsltExt As XSLTExtension = Nothing Dim xtrXML As System.Xml.XmlTextReader = Nothing Dim xw As Xml.XmlTextWriter = Nothing Dim sw As StringWriterWithEncoding = Nothing Dim strReturn As String = String.Empty Try 'Create the XslTransform object and load the stylesheet xst = New System.Xml.Xsl.XslCompiledTransform xtrXSLT = New System.Xml.XmlTextReader(New IO.StreamReader(xsltFileName)) xtrXSLT.ProhibitDtd = False xst.Load(xtrXSLT) 'Prepare the XML document to be transformed xtrXML = New System.Xml.XmlTextReader(xmlText, Xml.XmlNodeType.Document, Nothing) 'Prepare the output objects 'This prevents unprintable characters from being printed at the top of the resulting string sw = New StringWriterWithEncoding(New System.Text.UTF8Encoding(False)) xw = New Xml.XmlTextWriter(sw) 'Transform the XML document using the XSLT file and place the output in "sw" resolver = New System.Xml.XmlUrlResolver xal = New System.Xml.Xsl.XsltArgumentList xsltExt = New XSLTExtension xal.AddExtensionObject("urn:date-format", xsltExt) xst.Transform(xtrXML, xal, xw, resolver) strReturn = sw.ToString.Replace(" ", " ") 'Replace the   character with Catch ex As Exception RaiseEvent Exception(Me, New EMailExceptionEventArgs(ex)) Finally If Not xal Is Nothing Then xal = Nothing End If If Not sw Is Nothing Then sw.Close() sw = Nothing End If If Not xw Is Nothing Then xw.Close() xw = Nothing End If If Not xtrXML Is Nothing Then xtrXML.Close() xtrXML = Nothing End If If Not xtrXSLT Is Nothing Then xtrXSLT.Close() xtrXSLT = Nothing End If End Try Return strReturn End Function "Jody Gelowitz" <jgelowitz_nospam@blah.leevalley.com> wrote in message news:u5uzLnOeGHA.2188@TK2MSFTNGP04.phx.gbl... I have run into an issue with variable scope within an XSLT document that is translated in VS.NET 2.0. Under VS.NET 1.1 (XslTransform), this code works fine. However, when using VS.NET 2.0 (XslCompiledTransform), the exact same XSLT transformation fails with the error:System.Xml.Xsl.XslLoadException: The variable or parameter 'lastrecordwaskit' was duplicated within the same scope. An error occurred at (174,12). at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver) at System.Xml.Xsl.XslCompiledTransform.Load(XmlReader stylesheet) at MyProject.MyClass.TranslateXML(String xsltFileName, String xmlText) in C:\Source\MySolution\MyProject\MyClass.vb:line 155 I have included the XSL code below which is related to the issue. In order to maintain the previous value of "iskit", I am declaring a variable "lastrecordwaskit" at the end of the loop. Near the beginning of the loop, prior to the variable declaration of "lastrecordwaskit", I am checking for "position() > 1" before trying to access "lastrecordwaskit". In .NET 1.1, this would allow the "lastrecordwaskit" variable to be declared prior to it being accessed. In .NET 2.0, it appears that this will no longer work. I need to be able to access the previous value of a variable (or previous XML element) while inside of a loop. Are there any solutions to this problem with .NET 2.0? Thanks, Jody <xsl:for-each select="Order/Invoice/InvoiceDetails/InvoiceDetail"> <xsl:variable name="iskit"> <xsl:choose> <xsl:when test="@idt_set_master='N' and @idt_set_component_seq>0"> 1 </xsl:when> <xsl:otherwise> 0 </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:if test="position()>1"> <xsl:if test="$lastrecordwaskit=1 and $iskit=0"> <tr> <td> </td> </tr> </xsl:if> </xsl:if> {Additional Code ...} <xsl:variable name="lastrecordwaskit"><xsl:value-of select="$iskit"/></xsl:variable> </xsl:for-each> This is a bug in XslTransfom implementation. You should not rely on this bug
in production code. Best regards, Anton |
|||||||||||||||||||||||