internal override void Execute(Processor processor, ActionFrame frame) { Debug.Assert(processor != null && frame != null); ArrayList list = processor.NumberList; switch (frame.State) { case Initialized: Debug.Assert(frame != null); Debug.Assert(frame.NodeSet != null); list.Clear(); if (this.value != null) { object valueObject = SimplifyValue(processor.Evaluate(frame, this.valueKey)); double valueDouble = 0; try { valueDouble = XmlConvert.ToXPathDouble(valueObject); } catch (FormatException) {} if (0.5 <= valueDouble && valueDouble < double.PositiveInfinity) { Debug.Assert(!double.IsNaN(valueDouble), "I belive it should be filtered by if condition"); list.Add(Math.Floor(valueDouble + 0.5)); // See XPath round for detailes on the trick with Floor() } else { // It is an error if the number is NaN, infinite or less than 0.5; an XSLT processor may signal the error; // if it does not signal the error, it must recover by converting the number to a string as if by a call // to the string function and inserting the resulting string into the result tree. frame.StoredOutput = XmlConvert.ToXPathString(valueObject); goto case OutputNumber; } } else if (this.level == "any") { int number = numberAny(processor, frame); if (number != 0) { list.Add((double)number); } } else { bool multiple = (this.level == "multiple"); XPathNavigator contextNode = frame.Node; // context of xsl:number element. We using this node in MatchCountKey() XPathNavigator countNode = frame.Node.Clone(); // node we count for if (countNode.NodeType == XPathNodeType.Attribute) { countNode.MoveToParent(); } while (moveToCount(countNode, processor, contextNode)) { list.Insert(0, (double)numberCount(countNode, processor, contextNode)); if (!multiple || !countNode.MoveToParent()) { break; } } if (!checkFrom(processor, countNode)) { list.Clear(); } } /*CalculatingFormat:*/ frame.StoredOutput = Format(list, this.formatAvt == null ? this.formatList : ParseFormat(this.formatAvt.Evaluate(processor, frame)), this.langAvt == null ? this.lang : this.langAvt.Evaluate(processor, frame), this.letterAvt == null ? this.letter : ParseLetter(this.letterAvt.Evaluate(processor, frame)), this.groupingSepAvt == null ? this.groupingSep : this.groupingSepAvt.Evaluate(processor, frame), this.groupingSizeAvt == null ? this.groupingSize : this.groupingSizeAvt.Evaluate(processor, frame) ); goto case OutputNumber; case OutputNumber: Debug.Assert(frame.StoredOutput != null); if (!processor.TextEvent(frame.StoredOutput)) { frame.State = OutputNumber; break; } frame.Finished(); break; default: Debug.Fail("Invalid Number Action execution state"); break; } }
internal override void Execute(Processor processor, ActionFrame frame) { Debug.Assert(processor != null && frame != null); ArrayList list = processor.NumberList; switch (frame.State) { case Initialized: Debug.Assert(frame != null); Debug.Assert(frame.NodeSet != null); list.Clear(); if (this.value != null) { object valueObject = processor.Evaluate(frame, this.valueKey); double valueDouble = 0; try { valueDouble = Processor.ToDouble(valueObject); } catch (FormatException) {} if (0.5 <= valueDouble && valueDouble < double.PositiveInfinity) { Debug.Assert(! double.IsNaN(valueDouble), "I belive it should be filtered by if condition"); list.Add(Math.Floor(valueDouble + 0.5)); // See XPath round for detailes on the trick with Floor() } else { // It is an error if the number is NaN, infinite or less than 0.5; an XSLT processor may signal the error; // if it does not signal the error, it must recover by converting the number to a string as if by a call // to the string function and inserting the resulting string into the result tree. frame.StoredOutput = XmlConvert.ToXPathString(valueObject); goto case OutputNumber; } } else if (this.level == "any") { int number = numberAny(processor, frame); if (number != 0) { list.Add(number); } } else { bool multiple = (this.level == "multiple"); XPathNavigator contextNode = frame.Node; // context of xsl:number element. We using this node in MatchCountKey() XPathNavigator countNode = frame.Node.Clone(); // node we count for if(countNode.NodeType == XPathNodeType.Attribute) { countNode.MoveToParent(); } while(moveToCount(countNode, processor, contextNode)) { list.Insert(0, numberCount(countNode, processor, contextNode)); if(! multiple || ! countNode.MoveToParent()) { break; } } if(! checkFrom(processor, countNode)) { list.Clear(); } } /*CalculatingFormat:*/ frame.StoredOutput = Format(list, this.formatAvt == null ? this.formatList : ParseFormat(this.formatAvt.Evaluate(processor, frame)), this.langAvt == null ? this.lang : this.langAvt .Evaluate(processor, frame), this.letterAvt == null ? this.letter : ParseLetter(this.letterAvt.Evaluate(processor, frame)), this.groupingSepAvt == null ? this.groupingSep : this.groupingSepAvt .Evaluate(processor, frame), this.groupingSizeAvt == null ? this.groupingSize : this.groupingSizeAvt.Evaluate(processor, frame) ); goto case OutputNumber; case OutputNumber : Debug.Assert(frame.StoredOutput != null); if (! processor.TextEvent(frame.StoredOutput)) { frame.State = OutputNumber; break; } frame.Finished(); break; default: Debug.Fail("Invalid Number Action execution state"); break; } }