Beispiel #1
0
        private QilNode CompileFormatNumber(QilNode value, QilNode formatPicture, QilNode formatName)
        {
            _f.CheckDouble(value);
            _f.CheckString(formatPicture);
            XmlQualifiedName resolvedName;

            if (formatName == null)
            {
                resolvedName = new XmlQualifiedName();
                // formatName must be non-null in the f.InvokeFormatNumberDynamic() call below
                formatName = _f.String(string.Empty);
            }
            else
            {
                _f.CheckString(formatName);
                if (formatName.NodeType == QilNodeType.LiteralString)
                {
                    resolvedName = ResolveQNameThrow(/*ignoreDefaultNs:*/ true, formatName);
                }
                else
                {
                    resolvedName = null;
                }
            }

            if (resolvedName != null)
            {
                DecimalFormatDecl format;
                if (_compiler.DecimalFormats.Contains(resolvedName))
                {
                    format = _compiler.DecimalFormats[resolvedName];
                }
                else
                {
                    if (resolvedName != DecimalFormatDecl.Default.Name)
                    {
                        throw new XslLoadException(SR.Xslt_NoDecimalFormat, (string)(QilLiteral)formatName);
                    }
                    format = DecimalFormatDecl.Default;
                }

                // If both formatPicture and formatName are literal strings, there is no need to reparse
                // formatPicture on every execution of this format-number(). Instead, we create a DecimalFormatter
                // object on the first execution, save its index into a global variable, and reuse that object
                // on all subsequent executions.
                if (formatPicture.NodeType == QilNodeType.LiteralString)
                {
                    QilIterator fmtIdx = _f.Let(_f.InvokeRegisterDecimalFormatter(formatPicture, format));
                    fmtIdx.DebugName = _f.QName("formatter" + _formatterCnt++, XmlReservedNs.NsXslDebug).ToString();
                    _gloVars.Add(fmtIdx);
                    return(_f.InvokeFormatNumberStatic(value, fmtIdx));
                }

                _formatNumberDynamicUsed = true;
                QilNode name = _f.QName(resolvedName.Name, resolvedName.Namespace);
                return(_f.InvokeFormatNumberDynamic(value, formatPicture, name, formatName));
            }
            else
            {
                _formatNumberDynamicUsed = true;
                QilIterator i    = _f.Let(formatName);
                QilNode     name = ResolveQNameDynamic(/*ignoreDefaultNs:*/ true, i);
                return(_f.Loop(i, _f.InvokeFormatNumberDynamic(value, formatPicture, name, i)));
            }
        }
Beispiel #2
0
 public XsltFunctionFocus(QilIterator current)
 {
     Debug.Assert(current != null);
     _current = current;
 }
Beispiel #3
0
 public SingletonFocus(XPathQilFactory f)
 {
     _f         = f;
     _focusType = SingletonFocusType.None;
     _current   = null;
 }
Beispiel #4
0
 public QilNode Replace(QilNode inExpr, QilIterator from, QilIterator to)
 {
     this.from = from;
     this.to   = to;
     return(Visit(inExpr));
 }
Beispiel #5
0
 public LoopFocus(XPathQilFactory f)
 {
     _f       = f;
     _current = _cached = _last = null;
 }
Beispiel #6
0
 public void SetFocus(QilIterator current)
 {
     _current = current;
     _cached  = _last = null;
 }
Beispiel #7
0
 public SingletonFocus(XPathQilFactory f)
 {
     this.f    = f;
     focusType = SingletonFocusType.None;
     current   = null;
 }
Beispiel #8
0
 public void SetFocus(QilIterator current)
 {
     this.current = current;
     cached       = last = null;
 }
Beispiel #9
0
 public LoopFocus(XPathQilFactory f)
 {
     this.f  = f;
     current = cached = last = null;
 }
 public QilNode Replace(QilNode inExpr, QilIterator from, QilIterator to) {
     this.from = from;
     this.to   = to  ;
     return Visit(inExpr);
 }
        // "nodeset[predicate]"
        // XPath spec $3.3 (para 5)
        public virtual QilNode Predicate(QilNode nodeset, QilNode predicate, bool isReverseStep)
        {
            if (isReverseStep)
            {
                Debug.Assert(nodeset.NodeType == QilNodeType.DocOrderDistinct,
                             "ReverseAxe in Qil is actuly reverse and we compile them here in builder by wrapping to DocOrderDistinct()"
                             );
                // The trick here is that we unwarp it back, compile as regular predicate and wrap again.
                // this way this wat we hold invariant that path expresion are always DOD and make predicates on reverse axe
                // work as specified in XPath 2.0 FS: http://www.w3.org/TR/xquery-semantics/#id-axis-steps
                nodeset = ((QilUnary)nodeset).Child;
            }

            nodeset = f.EnsureNodeSet(nodeset);

            // Prepocess predicate: if (predicate is number) then predicate := (position() == predicate)
            if (!f.IsAnyType(predicate))
            {
                if (predicate.XmlType.TypeCode == XmlTypeCode.Double)
                {
                    predicate = f.Eq(GetCurrentPosition(), predicate);
                }
                else
                {
                    predicate = f.ConvertToBoolean(predicate);
                }
            }
            else
            {
                QilIterator i;
                predicate = f.Loop(i = f.Let(predicate),
                                   f.Conditional(f.IsType(i, T.Double),
                                                 f.Eq(GetCurrentPosition(), f.TypeAssert(i, T.DoubleX)),
                                                 f.ConvertToBoolean(i)
                                                 )
                                   );
            }


            QilNode result;

            if (numFixupLast != 0 && fixupVisitor.CountUnfixedLast(predicate) != 0)
            {
                // this subtree has unfixed last() nodes
                QilIterator cash = f.Let(nodeset);
                QilIterator size = f.Let(f.XsltConvert(f.Length(cash), T.DoubleX));
                QilIterator it   = f.For(cash);
                predicate         = fixupVisitor.Fixup(predicate, /*current:*/ it, /*last:*/ size);
                numFixupCurrent  -= fixupVisitor.numCurrent;
                numFixupPosition -= fixupVisitor.numPosition;
                numFixupLast     -= fixupVisitor.numLast;
                result            = f.Loop(cash, f.Loop(size, f.Filter(it, predicate)));
            }
            else
            {
                QilIterator it = f.For(nodeset);
                predicate         = fixupVisitor.Fixup(predicate, /*current:*/ it, /*last:*/ null);
                numFixupCurrent  -= fixupVisitor.numCurrent;
                numFixupPosition -= fixupVisitor.numPosition;
                numFixupLast     -= fixupVisitor.numLast;
                result            = f.Filter(it, predicate);
            }
            if (isReverseStep)
            {
                result = f.DocOrderDistinct(result);
            }
            return(result);
        }