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))); } }
public XsltFunctionFocus(QilIterator current) { Debug.Assert(current != null); _current = current; }
public SingletonFocus(XPathQilFactory f) { _f = f; _focusType = SingletonFocusType.None; _current = null; }
public QilNode Replace(QilNode inExpr, QilIterator from, QilIterator to) { this.from = from; this.to = to; return(Visit(inExpr)); }
public LoopFocus(XPathQilFactory f) { _f = f; _current = _cached = _last = null; }
public void SetFocus(QilIterator current) { _current = current; _cached = _last = null; }
public SingletonFocus(XPathQilFactory f) { this.f = f; focusType = SingletonFocusType.None; current = null; }
public void SetFocus(QilIterator current) { this.current = current; cached = last = null; }
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); }