Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / XmlUtils / System / Xml / Xsl / XPath / XPathQilFactory.cs / 1305376 / XPathQilFactory.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
using System.Diagnostics;
using System.Xml.Schema;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.Runtime;
namespace System.Xml.Xsl.XPath {
using Res = System.Xml.Utils.Res;
using T = XmlQueryTypeFactory;
internal class XPathQilFactory : QilPatternFactory {
public XPathQilFactory(QilFactory f, bool debug) : base(f, debug) {
}
// Helper methods used in addition to QilPatternFactory's ones
public QilNode Error(string res, QilNode args) {
return Error(InvokeFormatMessage(String(res), args));
}
public QilNode Error(ISourceLineInfo lineInfo, string res, params string[] args) {
return Error(String(XslLoadException.CreateMessage(lineInfo, res, args)));
}
public QilIterator FirstNode(QilNode n) {
CheckNodeSet(n);
QilIterator i = For(DocOrderDistinct(n));
return For(Filter(i, Eq(PositionOf(i), Int32(1))));
}
public bool IsAnyType(QilNode n) {
XmlQueryType xt = n.XmlType;
bool result = !(xt.IsStrict || xt.IsNode);
Debug.Assert(result == (xt.TypeCode == XmlTypeCode.Item || xt.TypeCode == XmlTypeCode.AnyAtomicType), "What else can it be?");
return result;
}
[Conditional("DEBUG")]
public void CheckAny(QilNode n) {
Debug.Assert(n != null && IsAnyType(n), "Must be of 'any' type");
}
[Conditional("DEBUG")]
public void CheckNode(QilNode n) {
Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode, "Must be a singleton node");
}
[Conditional("DEBUG")]
public void CheckNodeSet(QilNode n) {
Debug.Assert(n != null && n.XmlType.IsNode, "Must be a node-set");
}
[Conditional("DEBUG")]
public void CheckNodeNotRtf(QilNode n) {
Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode && n.XmlType.IsNotRtf, "Must be a singleton node and not an Rtf");
}
[Conditional("DEBUG")]
public void CheckString(QilNode n) {
Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringX), "Must be a singleton string");
}
[Conditional("DEBUG")]
public void CheckStringS(QilNode n) {
Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringXS), "Must be a sequence of strings");
}
[Conditional("DEBUG")]
public void CheckDouble(QilNode n) {
Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.DoubleX), "Must be a singleton Double");
}
[Conditional("DEBUG")]
public void CheckBool(QilNode n) {
Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.BooleanX), "Must be a singleton Bool");
}
// Return true if inferred type of the given expression is never a subtype of T.NodeS
public bool CannotBeNodeSet(QilNode n) {
XmlQueryType xt = n.XmlType;
// Do not report compile error if n is a VarPar, whose inferred type forbids nodes (SQLBUDT 339398)
return xt.IsAtomicValue && !xt.IsEmpty && !(n is QilIterator);
}
public QilNode SafeDocOrderDistinct(QilNode n) {
XmlQueryType xt = n.XmlType;
if (xt.MaybeMany) {
if (xt.IsNode && xt.IsNotRtf) {
// node-set
return DocOrderDistinct(n);
} else if (!xt.IsAtomicValue) {
QilIterator i;
return Loop(i = Let(n),
Conditional(Gt(Length(i), Int32(1)),
DocOrderDistinct(TypeAssert(i, T.NodeNotRtfS)),
i
)
);
}
}
return n;
}
public QilNode InvokeFormatMessage(QilNode res, QilNode args) {
CheckString(res);
CheckStringS(args);
return XsltInvokeEarlyBound(QName("format-message"),
XsltMethods.FormatMessage, T.StringX, new QilNode[] { res, args }
);
}
#region Comparisons
public QilNode InvokeEqualityOperator(QilNodeType op, QilNode left, QilNode right) {
Debug.Assert(op == QilNodeType.Eq || op == QilNodeType.Ne);
double opCode;
left = TypeAssert(left, T.ItemS);
right = TypeAssert(right, T.ItemS);
switch (op) {
case QilNodeType.Eq: opCode = (double)XsltLibrary.ComparisonOperator.Eq; break;
default: opCode = (double)XsltLibrary.ComparisonOperator.Ne; break;
}
return XsltInvokeEarlyBound(QName("EqualityOperator"),
XsltMethods.EqualityOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right }
);
}
public QilNode InvokeRelationalOperator(QilNodeType op, QilNode left, QilNode right) {
Debug.Assert(op == QilNodeType.Lt || op == QilNodeType.Le || op == QilNodeType.Gt || op == QilNodeType.Ge);
double opCode;
left = TypeAssert(left, T.ItemS);
right = TypeAssert(right, T.ItemS);
switch (op) {
case QilNodeType.Lt: opCode = (double)XsltLibrary.ComparisonOperator.Lt; break;
case QilNodeType.Le: opCode = (double)XsltLibrary.ComparisonOperator.Le; break;
case QilNodeType.Gt: opCode = (double)XsltLibrary.ComparisonOperator.Gt; break;
default: opCode = (double)XsltLibrary.ComparisonOperator.Ge; break;
}
return XsltInvokeEarlyBound(QName("RelationalOperator"),
XsltMethods.RelationalOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right }
);
}
#endregion
#region Type Conversions
[Conditional("DEBUG")]
private void ExpectAny(QilNode n) {
Debug.Assert(IsAnyType(n), "Unexpected expression type: " + n.XmlType.ToString());
}
public QilNode ConvertToType(XmlTypeCode requiredType, QilNode n) {
switch (requiredType) {
case XmlTypeCode.String : return ConvertToString(n);
case XmlTypeCode.Double : return ConvertToNumber(n);
case XmlTypeCode.Boolean : return ConvertToBoolean(n);
case XmlTypeCode.Node : return EnsureNodeSet(n);
case XmlTypeCode.Item : return n;
default : Debug.Fail("Unexpected XmlTypeCode: " + requiredType); return null;
}
}
// XPath spec $4.2, string()
public QilNode ConvertToString(QilNode n) {
switch (n.XmlType.TypeCode) {
case XmlTypeCode.Boolean :
return (
n.NodeType == QilNodeType.True ? (QilNode) String("true") :
n.NodeType == QilNodeType.False ? (QilNode) String("false") :
/*default: */ (QilNode) Conditional(n, String("true"), String("false"))
);
case XmlTypeCode.Double :
return (n.NodeType == QilNodeType.LiteralDouble
? (QilNode) String(XPathConvert.DoubleToString((double)(QilLiteral)n))
: (QilNode) XsltConvert(n, T.StringX)
);
case XmlTypeCode.String :
return n;
default :
if (n.XmlType.IsNode) {
return XPathNodeValue(SafeDocOrderDistinct(n));
}
ExpectAny(n);
return XsltConvert(n, T.StringX);
}
}
// XPath spec $4.3, boolean()
public QilNode ConvertToBoolean(QilNode n) {
switch (n.XmlType.TypeCode) {
case XmlTypeCode.Boolean :
return n;
case XmlTypeCode.Double :
// (x < 0 || 0 < x) == (x != 0) && !Double.IsNaN(x)
QilIterator i;
return (n.NodeType == QilNodeType.LiteralDouble
? Boolean((double)(QilLiteral)n < 0 || 0 < (double)(QilLiteral)n)
: Loop(i = Let(n), Or(Lt(i, Double(0)), Lt(Double(0), i)))
);
case XmlTypeCode.String :
return (n.NodeType == QilNodeType.LiteralString
? Boolean(((string)(QilLiteral)n).Length != 0)
: Ne(StrLength(n), Int32(0))
);
default:
if (n.XmlType.IsNode) {
return Not(IsEmpty(n));
}
ExpectAny(n);
return XsltConvert(n, T.BooleanX);
}
}
// XPath spec $4.4, number()
public QilNode ConvertToNumber(QilNode n) {
switch (n.XmlType.TypeCode) {
case XmlTypeCode.Boolean :
return (
n.NodeType == QilNodeType.True ? (QilNode) Double(1) :
n.NodeType == QilNodeType.False ? (QilNode) Double(0) :
/*default: */ (QilNode) Conditional(n, Double(1), Double(0))
);
case XmlTypeCode.Double :
return n;
case XmlTypeCode.String :
return XsltConvert(n, T.DoubleX);
default:
if (n.XmlType.IsNode) {
return XsltConvert(XPathNodeValue(SafeDocOrderDistinct(n)), T.DoubleX);
}
ExpectAny(n);
return XsltConvert(n, T.DoubleX);
}
}
public QilNode ConvertToNode(QilNode n) {
if (n.XmlType.IsNode && n.XmlType.IsNotRtf && n.XmlType.IsSingleton) {
return n;
}
return XsltConvert(n, T.NodeNotRtf);
}
public QilNode ConvertToNodeSet(QilNode n) {
if (n.XmlType.IsNode && n.XmlType.IsNotRtf) {
return n;
}
return XsltConvert(n, T.NodeNotRtfS);
}
// Returns null if the given expression is never a node-set
public QilNode TryEnsureNodeSet(QilNode n) {
if (n.XmlType.IsNode && n.XmlType.IsNotRtf) {
return n;
}
if (CannotBeNodeSet(n)) {
return null;
}
// Ensure it is not an Rtf at runtime
return InvokeEnsureNodeSet(n);
}
// Throws an exception if the given expression is never a node-set
public QilNode EnsureNodeSet(QilNode n) {
QilNode result = TryEnsureNodeSet(n);
if (result == null) {
throw new XPathCompileException(Res.XPath_NodeSetExpected);
}
return result;
}
public QilNode InvokeEnsureNodeSet(QilNode n) {
return XsltInvokeEarlyBound(QName("ensure-node-set"),
XsltMethods.EnsureNodeSet, T.NodeSDod, new QilNode[] { n }
);
}
#endregion
#region Other XPath Functions
public QilNode Id(QilNode context, QilNode id) {
CheckNodeNotRtf(context);
if (id.XmlType.IsSingleton) {
return Deref(context, ConvertToString(id));
}
QilIterator i;
return Loop(i = For(id), Deref(context, ConvertToString(i)));
}
public QilNode InvokeStartsWith(QilNode str1, QilNode str2) {
CheckString(str1);
CheckString(str2);
return XsltInvokeEarlyBound(QName("starts-with"),
XsltMethods.StartsWith, T.BooleanX, new QilNode[] { str1, str2 }
);
}
public QilNode InvokeContains(QilNode str1, QilNode str2) {
CheckString(str1);
CheckString(str2);
return XsltInvokeEarlyBound(QName("contains"),
XsltMethods.Contains, T.BooleanX, new QilNode[] { str1, str2 }
);
}
public QilNode InvokeSubstringBefore(QilNode str1, QilNode str2) {
CheckString(str1);
CheckString(str2);
return XsltInvokeEarlyBound(QName("substring-before"),
XsltMethods.SubstringBefore, T.StringX, new QilNode[] { str1, str2 }
);
}
public QilNode InvokeSubstringAfter(QilNode str1, QilNode str2) {
CheckString(str1);
CheckString(str2);
return XsltInvokeEarlyBound(QName("substring-after"),
XsltMethods.SubstringAfter, T.StringX, new QilNode[] { str1, str2 }
);
}
public QilNode InvokeSubstring(QilNode str, QilNode start) {
CheckString(str);
CheckDouble(start);
return XsltInvokeEarlyBound(QName("substring"),
XsltMethods.Substring2, T.StringX, new QilNode[] { str, start }
);
}
public QilNode InvokeSubstring(QilNode str, QilNode start, QilNode length) {
CheckString(str);
CheckDouble(start);
CheckDouble(length);
return XsltInvokeEarlyBound(QName("substring"),
XsltMethods.Substring3, T.StringX, new QilNode[] { str, start, length }
);
}
public QilNode InvokeNormalizeSpace(QilNode str) {
CheckString(str);
return XsltInvokeEarlyBound(QName("normalize-space"),
XsltMethods.NormalizeSpace, T.StringX, new QilNode[] { str }
);
}
public QilNode InvokeTranslate(QilNode str1, QilNode str2, QilNode str3) {
CheckString(str1);
CheckString(str2);
CheckString(str3);
return XsltInvokeEarlyBound(QName("translate"),
XsltMethods.Translate, T.StringX, new QilNode[] { str1, str2, str3 }
);
}
public QilNode InvokeLang(QilNode lang, QilNode context) {
CheckString(lang);
CheckNodeNotRtf(context);
return XsltInvokeEarlyBound(QName("lang"),
XsltMethods.Lang, T.BooleanX, new QilNode[] { lang, context }
);
}
public QilNode InvokeFloor(QilNode value) {
CheckDouble(value);
return XsltInvokeEarlyBound(QName("floor"),
XsltMethods.Floor, T.DoubleX, new QilNode[] { value }
);
}
public QilNode InvokeCeiling(QilNode value) {
CheckDouble(value);
return XsltInvokeEarlyBound(QName("ceiling"),
XsltMethods.Ceiling, T.DoubleX, new QilNode[] { value }
);
}
public QilNode InvokeRound(QilNode value) {
CheckDouble(value);
return XsltInvokeEarlyBound(QName("round"),
XsltMethods.Round, T.DoubleX, new QilNode[] { value }
);
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FixedBufferAttribute.cs
- ProfileInfo.cs
- ConnectionPointCookie.cs
- TextShapeableCharacters.cs
- DispatcherProcessingDisabled.cs
- PageAsyncTaskManager.cs
- QueryContinueDragEventArgs.cs
- TextFragmentEngine.cs
- AspNetHostingPermission.cs
- OverlappedContext.cs
- KeyGestureConverter.cs
- ProcessRequestArgs.cs
- XmlLangPropertyAttribute.cs
- MatrixAnimationUsingKeyFrames.cs
- CheckBox.cs
- SmiRequestExecutor.cs
- ModelUIElement3D.cs
- DetailsViewPageEventArgs.cs
- InputScope.cs
- HttpPostedFile.cs
- XmlBaseReader.cs
- UnionCodeGroup.cs
- Error.cs
- SizeAnimation.cs
- KnownBoxes.cs
- BlockCollection.cs
- ComplexBindingPropertiesAttribute.cs
- SymLanguageVendor.cs
- KeyNotFoundException.cs
- NameValueSectionHandler.cs
- Scanner.cs
- oledbconnectionstring.cs
- ReadOnlyDictionary.cs
- BindingListCollectionView.cs
- TemplatedMailWebEventProvider.cs
- BamlLocalizableResourceKey.cs
- IisTraceWebEventProvider.cs
- InvalidWMPVersionException.cs
- LabelAutomationPeer.cs
- CodeDomSerializationProvider.cs
- ManagedIStream.cs
- TagMapCollection.cs
- ContentHostHelper.cs
- ResourceDescriptionAttribute.cs
- ApplicationHost.cs
- WebPartsPersonalizationAuthorization.cs
- SID.cs
- CachedBitmap.cs
- OdbcConnectionPoolProviderInfo.cs
- CompleteWizardStep.cs
- DoubleLinkList.cs
- ChtmlTextBoxAdapter.cs
- HtmlTextArea.cs
- TdsParser.cs
- HitTestWithGeometryDrawingContextWalker.cs
- ObjectDataSourceEventArgs.cs
- BindingBase.cs
- PassportPrincipal.cs
- Operator.cs
- ToolStripItemEventArgs.cs
- SafeBitVector32.cs
- AppDomainEvidenceFactory.cs
- PtsHelper.cs
- complextypematerializer.cs
- ProcessManager.cs
- ProcessHostFactoryHelper.cs
- LinqDataSourceStatusEventArgs.cs
- ExceptionUtil.cs
- StorageEndPropertyMapping.cs
- SqlDataSourceView.cs
- Helpers.cs
- MenuItemCollection.cs
- ChineseLunisolarCalendar.cs
- RoutedEventHandlerInfo.cs
- PrimitiveSchema.cs
- DataConnectionHelper.cs
- TreeViewAutomationPeer.cs
- NamespaceMapping.cs
- externdll.cs
- HGlobalSafeHandle.cs
- MenuItemCollectionEditor.cs
- XmlNodeComparer.cs
- DynamicDocumentPaginator.cs
- CSharpCodeProvider.cs
- StringDictionaryEditor.cs
- URLMembershipCondition.cs
- LogSwitch.cs
- securitymgrsite.cs
- XmlSignificantWhitespace.cs
- BaseDataList.cs
- ManagementPath.cs
- TextDecorationUnitValidation.cs
- SrgsDocumentParser.cs
- LockCookie.cs
- TraceLevelStore.cs
- TargetException.cs
- DesignParameter.cs
- OperationInfo.cs
- ValidationResult.cs
- MasterPage.cs