Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / XmlUtils / System / Xml / Xsl / Xslt / XPathPatternParser.cs / 1 / XPathPatternParser.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; using System.Xml; using System.Xml.Xsl.Qil; using System.Xml.Xsl.XPath; namespace System.Xml.Xsl.Xslt { using XPathParser = XPathParser; using XPathNodeType = System.Xml.XPath.XPathNodeType; using Res = System.Xml.Utils.Res; internal class XPathPatternParser { public interface IPatternBuilder : IXPathBuilder { IXPathBuilder GetPredicateBuilder(QilNode context); } XPathScanner scanner; IPatternBuilder ptrnBuilder; XPathParser predicateParser = new XPathParser(); public QilNode Parse(XPathScanner scanner, IPatternBuilder ptrnBuilder) { Debug.Assert(this.scanner == null && this.ptrnBuilder == null); Debug.Assert(scanner != null && ptrnBuilder != null); QilNode result = null; ptrnBuilder.StartBuild(); try { this.scanner = scanner; this.ptrnBuilder = ptrnBuilder; result = this.ParsePattern(); this.scanner.CheckToken(LexKind.Eof); } finally { result = ptrnBuilder.EndBuild(result); #if DEBUG this.ptrnBuilder = null; this.scanner = null; #endif } return result; } /* * Pattern ::= LocationPathPattern ('|' LocationPathPattern)* */ private QilNode ParsePattern() { QilNode opnd = ParseLocationPathPattern(); while (scanner.Kind == LexKind.Union) { scanner.NextLex(); opnd = ptrnBuilder.Operator(XPathOperator.Union, opnd, ParseLocationPathPattern()); } return opnd; } /* * LocationPathPattern ::= '/' RelativePathPattern? | '//'? RelativePathPattern | IdKeyPattern (('/' | '//') RelativePathPattern)? */ private QilNode ParseLocationPathPattern() { QilNode opnd; switch (scanner.Kind) { case LexKind.Slash : scanner.NextLex(); opnd = ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null); if (XPathParser.IsStep(scanner.Kind)) { opnd = ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); } return opnd; case LexKind.SlashSlash : scanner.NextLex(); return ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null), ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() ) ); case LexKind.Name : if (scanner.CanBeFunction && scanner.Prefix.Length == 0 && (scanner.Name == "id" || scanner.Name == "key")) { opnd = ParseIdKeyPattern(); switch (scanner.Kind) { case LexKind.Slash : scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); break; case LexKind.SlashSlash : scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() ) ); break; } return opnd; } break; } opnd = ParseRelativePathPattern(); return opnd; } /* * IdKeyPattern ::= 'id' '(' Literal ')' | 'key' '(' Literal ',' Literal ')' */ private QilNode ParseIdKeyPattern() { Debug.Assert(scanner.CanBeFunction); Debug.Assert(scanner.Prefix.Length == 0); Debug.Assert(scanner.Name == "id" || scanner.Name == "key"); List args = new List (2); if (scanner.Name == "id") { scanner.NextLex(); scanner.PassToken(LexKind.LParens); scanner.CheckToken(LexKind.String); args.Add(ptrnBuilder.String(scanner.StringValue)); scanner.NextLex(); scanner.PassToken(LexKind.RParens); return ptrnBuilder.Function("", "id", args); } else { scanner.NextLex(); scanner.PassToken(LexKind.LParens); scanner.CheckToken(LexKind.String); args.Add(ptrnBuilder.String(scanner.StringValue)); scanner.NextLex(); scanner.PassToken(LexKind.Comma); scanner.CheckToken(LexKind.String); args.Add(ptrnBuilder.String(scanner.StringValue)); scanner.NextLex(); scanner.PassToken(LexKind.RParens); return ptrnBuilder.Function("", "key", args); } } /* * RelativePathPattern ::= StepPattern (('/' | '//') StepPattern)* */ private QilNode ParseRelativePathPattern() { QilNode opnd = ParseStepPattern(); if (scanner.Kind == LexKind.Slash) { scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); } else if (scanner.Kind == LexKind.SlashSlash) { scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() ) ); } return opnd; } /* * StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate* * ChildOrAttributeAxisSpecifier ::= @ ? | ('child' | 'attribute') '::' */ private QilNode ParseStepPattern() { QilNode opnd; XPathAxis axis; switch (scanner.Kind) { case LexKind.Dot: case LexKind.DotDot: throw scanner.CreateException(Res.XPath_InvalidAxisInPattern); case LexKind.At: //>> '@' axis = XPathAxis.Attribute; scanner.NextLex(); break; case LexKind.Axis: //>> AxisName '::' axis = XPathParser.GetAxis(scanner.Name, scanner); if (axis != XPathAxis.Child && axis != XPathAxis.Attribute) { throw scanner.CreateException(Res.XPath_InvalidAxisInPattern); } scanner.NextLex(); break; case LexKind.Name: case LexKind.Star: // NodeTest must start with Name or '*' axis = XPathAxis.Child; break; default: throw scanner.CreateException(Res.XPath_UnexpectedToken, scanner.RawValue); } XPathNodeType nodeType; string nodePrefix, nodeName; XPathParser.InternalParseNodeTest(scanner, axis, out nodeType, out nodePrefix, out nodeName); opnd = ptrnBuilder.Axis(axis, nodeType, nodePrefix, nodeName); while (scanner.Kind == LexKind.LBracket) { opnd = ptrnBuilder.Predicate(opnd, ParsePredicate(opnd), /*reverseStep:*/false); } return opnd; } /* * Predicate ::= '[' Expr ']' */ private QilNode ParsePredicate(QilNode context) { Debug.Assert(scanner.Kind == LexKind.LBracket); scanner.NextLex(); QilNode result = predicateParser.Parse(scanner, ptrnBuilder.GetPredicateBuilder(context), LexKind.RBracket); Debug.Assert(scanner.Kind == LexKind.RBracket); scanner.NextLex(); return result; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; using System.Xml; using System.Xml.Xsl.Qil; using System.Xml.Xsl.XPath; namespace System.Xml.Xsl.Xslt { using XPathParser = XPathParser; using XPathNodeType = System.Xml.XPath.XPathNodeType; using Res = System.Xml.Utils.Res; internal class XPathPatternParser { public interface IPatternBuilder : IXPathBuilder { IXPathBuilder GetPredicateBuilder(QilNode context); } XPathScanner scanner; IPatternBuilder ptrnBuilder; XPathParser predicateParser = new XPathParser(); public QilNode Parse(XPathScanner scanner, IPatternBuilder ptrnBuilder) { Debug.Assert(this.scanner == null && this.ptrnBuilder == null); Debug.Assert(scanner != null && ptrnBuilder != null); QilNode result = null; ptrnBuilder.StartBuild(); try { this.scanner = scanner; this.ptrnBuilder = ptrnBuilder; result = this.ParsePattern(); this.scanner.CheckToken(LexKind.Eof); } finally { result = ptrnBuilder.EndBuild(result); #if DEBUG this.ptrnBuilder = null; this.scanner = null; #endif } return result; } /* * Pattern ::= LocationPathPattern ('|' LocationPathPattern)* */ private QilNode ParsePattern() { QilNode opnd = ParseLocationPathPattern(); while (scanner.Kind == LexKind.Union) { scanner.NextLex(); opnd = ptrnBuilder.Operator(XPathOperator.Union, opnd, ParseLocationPathPattern()); } return opnd; } /* * LocationPathPattern ::= '/' RelativePathPattern? | '//'? RelativePathPattern | IdKeyPattern (('/' | '//') RelativePathPattern)? */ private QilNode ParseLocationPathPattern() { QilNode opnd; switch (scanner.Kind) { case LexKind.Slash : scanner.NextLex(); opnd = ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null); if (XPathParser.IsStep(scanner.Kind)) { opnd = ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); } return opnd; case LexKind.SlashSlash : scanner.NextLex(); return ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null), ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() ) ); case LexKind.Name : if (scanner.CanBeFunction && scanner.Prefix.Length == 0 && (scanner.Name == "id" || scanner.Name == "key")) { opnd = ParseIdKeyPattern(); switch (scanner.Kind) { case LexKind.Slash : scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); break; case LexKind.SlashSlash : scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() ) ); break; } return opnd; } break; } opnd = ParseRelativePathPattern(); return opnd; } /* * IdKeyPattern ::= 'id' '(' Literal ')' | 'key' '(' Literal ',' Literal ')' */ private QilNode ParseIdKeyPattern() { Debug.Assert(scanner.CanBeFunction); Debug.Assert(scanner.Prefix.Length == 0); Debug.Assert(scanner.Name == "id" || scanner.Name == "key"); List args = new List (2); if (scanner.Name == "id") { scanner.NextLex(); scanner.PassToken(LexKind.LParens); scanner.CheckToken(LexKind.String); args.Add(ptrnBuilder.String(scanner.StringValue)); scanner.NextLex(); scanner.PassToken(LexKind.RParens); return ptrnBuilder.Function("", "id", args); } else { scanner.NextLex(); scanner.PassToken(LexKind.LParens); scanner.CheckToken(LexKind.String); args.Add(ptrnBuilder.String(scanner.StringValue)); scanner.NextLex(); scanner.PassToken(LexKind.Comma); scanner.CheckToken(LexKind.String); args.Add(ptrnBuilder.String(scanner.StringValue)); scanner.NextLex(); scanner.PassToken(LexKind.RParens); return ptrnBuilder.Function("", "key", args); } } /* * RelativePathPattern ::= StepPattern (('/' | '//') StepPattern)* */ private QilNode ParseRelativePathPattern() { QilNode opnd = ParseStepPattern(); if (scanner.Kind == LexKind.Slash) { scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern()); } else if (scanner.Kind == LexKind.SlashSlash) { scanner.NextLex(); opnd = ptrnBuilder.JoinStep(opnd, ptrnBuilder.JoinStep( ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativePathPattern() ) ); } return opnd; } /* * StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate* * ChildOrAttributeAxisSpecifier ::= @ ? | ('child' | 'attribute') '::' */ private QilNode ParseStepPattern() { QilNode opnd; XPathAxis axis; switch (scanner.Kind) { case LexKind.Dot: case LexKind.DotDot: throw scanner.CreateException(Res.XPath_InvalidAxisInPattern); case LexKind.At: //>> '@' axis = XPathAxis.Attribute; scanner.NextLex(); break; case LexKind.Axis: //>> AxisName '::' axis = XPathParser.GetAxis(scanner.Name, scanner); if (axis != XPathAxis.Child && axis != XPathAxis.Attribute) { throw scanner.CreateException(Res.XPath_InvalidAxisInPattern); } scanner.NextLex(); break; case LexKind.Name: case LexKind.Star: // NodeTest must start with Name or '*' axis = XPathAxis.Child; break; default: throw scanner.CreateException(Res.XPath_UnexpectedToken, scanner.RawValue); } XPathNodeType nodeType; string nodePrefix, nodeName; XPathParser.InternalParseNodeTest(scanner, axis, out nodeType, out nodePrefix, out nodeName); opnd = ptrnBuilder.Axis(axis, nodeType, nodePrefix, nodeName); while (scanner.Kind == LexKind.LBracket) { opnd = ptrnBuilder.Predicate(opnd, ParsePredicate(opnd), /*reverseStep:*/false); } return opnd; } /* * Predicate ::= '[' Expr ']' */ private QilNode ParsePredicate(QilNode context) { Debug.Assert(scanner.Kind == LexKind.LBracket); scanner.NextLex(); QilNode result = predicateParser.Parse(scanner, ptrnBuilder.GetPredicateBuilder(context), LexKind.RBracket); Debug.Assert(scanner.Kind == LexKind.RBracket); scanner.NextLex(); return result; } } } // 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
- BitmapSourceSafeMILHandle.cs
- TextTreeRootTextBlock.cs
- DesignerEventService.cs
- ProtectedConfigurationSection.cs
- MetadataArtifactLoaderResource.cs
- MessageQueueCriteria.cs
- DelayDesigner.cs
- PrincipalPermission.cs
- DbConnectionFactory.cs
- FontTypeConverter.cs
- LocatorPartList.cs
- SafeFileMappingHandle.cs
- PasswordDeriveBytes.cs
- filewebresponse.cs
- Formatter.cs
- DataGridCell.cs
- SignedPkcs7.cs
- EUCJPEncoding.cs
- XmlNodeChangedEventManager.cs
- AutomationEventArgs.cs
- RightsManagementSuppressedStream.cs
- HebrewCalendar.cs
- LoginUtil.cs
- TypeDescriptionProvider.cs
- PageWrapper.cs
- EmptyStringExpandableObjectConverter.cs
- ExtentCqlBlock.cs
- PointLightBase.cs
- ListView.cs
- SizeAnimationClockResource.cs
- IsolationInterop.cs
- CommandField.cs
- SessionParameter.cs
- DbReferenceCollection.cs
- initElementDictionary.cs
- XmlElementAttributes.cs
- QilXmlWriter.cs
- EmptyControlCollection.cs
- HttpPostProtocolReflector.cs
- HighlightComponent.cs
- DataContractSerializerSection.cs
- WebServiceEnumData.cs
- CroppedBitmap.cs
- SoapUnknownHeader.cs
- TypeSemantics.cs
- HttpResponseInternalWrapper.cs
- SqlProviderManifest.cs
- RemotingAttributes.cs
- ResponseStream.cs
- ConnectionsZone.cs
- precedingsibling.cs
- CommandSet.cs
- GlobalProxySelection.cs
- _ScatterGatherBuffers.cs
- XmlSerializerOperationGenerator.cs
- TabControlToolboxItem.cs
- TextDecorationUnitValidation.cs
- TableProviderWrapper.cs
- CommonProperties.cs
- DbConnectionPoolOptions.cs
- WorkItem.cs
- PageParserFilter.cs
- DynamicDataResources.Designer.cs
- XmlSchemaInfo.cs
- ImageMapEventArgs.cs
- NativeRecognizer.cs
- FormsAuthenticationTicket.cs
- EntityDataSourceQueryBuilder.cs
- BinaryFormatterWriter.cs
- DataPointer.cs
- HttpModuleAction.cs
- DropDownHolder.cs
- ConfigurationManager.cs
- CategoriesDocumentFormatter.cs
- WindowsListBox.cs
- CodeSubDirectoriesCollection.cs
- DependencyObjectPropertyDescriptor.cs
- DBCSCodePageEncoding.cs
- Image.cs
- WebMessageEncodingElement.cs
- DocumentProperties.cs
- ByeOperation11AsyncResult.cs
- MediaCommands.cs
- ReadOnlyDictionary.cs
- ColumnResizeUndoUnit.cs
- FixedPage.cs
- WebPartVerbCollection.cs
- HttpCapabilitiesBase.cs
- ArithmeticException.cs
- ApplicationSecurityManager.cs
- QueryAccessibilityHelpEvent.cs
- WorkflowInspectionServices.cs
- AsyncStreamReader.cs
- SQLStringStorage.cs
- WebPartConnectionCollection.cs
- TransformCollection.cs
- WebDescriptionAttribute.cs
- SafeCoTaskMem.cs
- SystemIPAddressInformation.cs
- RoutedUICommand.cs