Update of /cvsroot/mvp-xml/XPointer/v2/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18461/v2/src Added Files: .cvsignore AssemblyInfo.cs ElementSchemaPointerPart.cs IDAssuredValidatingReader.cs LexUtils.cs Pointer.cs PointerPart.cs SR.cs SR.resx SchemaBasedPointer.cs ShorthandPointer.cs XPath1SchemaPointerPart.cs XPointer.csproj XPointerException.cs XPointerLexer.cs XPointerParser.cs XPointerReader.cs XPointerSchema.cs XPointerSchemaPointerPart.cs XmlnsSchemaPointerPart.cs changelog.txt Log Message: --- NEW FILE: IDAssuredValidatingReader.cs --- #region using using System.Xml; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// Auxillary XmlReader that always reports dummy DOCTYPE. This is done /// to turn on support for id() function in XML Schema defined XML documents. /// See http://www.tkachenko.com/blog/archives/000060.html. /// </summary> internal class IdAssuredValidatingReader : XmlValidatingReader { #region private members private bool _exposeDummyDoctype; private bool _isInProlog = true; #endregion #region constructors /// <summary> /// Constructs <c>IdAssuredValidatingReader</c> on top of another reader. /// </summary> /// <param name="r"></param> public IdAssuredValidatingReader(XmlReader r) : base (r) {} #endregion #region XmlValidatingReader overrides /// <summary>See <see cref="XmlValidatingReader.NodeType"/>.</summary> public override XmlNodeType NodeType { get { return _exposeDummyDoctype ? XmlNodeType.DocumentType : base.NodeType; } } /// <summary>See <see cref="XmlValidatingReader.MoveToNextAttribute"/>.</summary> public override bool MoveToNextAttribute() { return _exposeDummyDoctype? false : base.MoveToNextAttribute(); } /// <summary>See <see cref="XmlValidatingReader.Read"/>.</summary> public override bool Read() { if (_isInProlog) { if (!_exposeDummyDoctype) { //We are looking for the very first element bool baseRead = base.Read(); if (base.NodeType == XmlNodeType.Element) { _exposeDummyDoctype = true; return true; } else if (base.NodeType == XmlNodeType.DocumentType) { //Document has own DOCTYPE, switch back to normal flow _exposeDummyDoctype = false; _isInProlog = false; return true; } else { return baseRead; } } else { //Done, switch back to normal flow _exposeDummyDoctype = false; _isInProlog = false; return true; } } else return base.Read(); } #endregion } } --- NEW FILE: .cvsignore --- bin obj *.user *.suo --- NEW FILE: Pointer.cs --- #region using using System; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// Abstract XPointer pointer. /// </summary> public abstract class Pointer { #region public methods /// <summary> /// Parses XPointer pointer and compiles it into /// an instance of <see cref="Pointer"/> class. /// </summary> /// <param name="xpointer">XPointer pointer</param> /// <returns>Parsed and compiled XPointer</returns> public static Pointer Compile(string xpointer) { return XPointerParser.ParseXPointer(xpointer); } /// <summary> /// Evaluates <see cref="XPointer"/> pointer and returns /// iterator over pointed nodes. /// </summary> /// <param name="nav">Navigator to evaluate the /// <see cref="XPointer"/> on.</param> /// <returns><see cref="XPathNodeIterator"/> over pointed nodes. Note - this iterator is moved to the first node already.</returns> public abstract XPathNodeIterator Evaluate(XPathNavigator nav); #endregion } } --- NEW FILE: SchemaBasedPointer.cs --- #region using using System; using System.Collections.Generic; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// SchemaBased XPointer pointer. /// </summary> internal class SchemaBasedPointer : Pointer { #region private members private IList<PointerPart> _parts; private string _xpointer; #endregion #region constructors /// <summary> /// Creates scheme based XPointer given list of pointer parts. /// </summary> /// <param name="parts">List of pointer parts</param> /// <param name="xpointer">String representation of the XPointer /// (for error diagnostics)</param> public SchemaBasedPointer(IList<PointerPart> parts, string xpointer) { _parts = parts; _xpointer = xpointer; } #endregion #region Pointer overrides /// <summary> /// Evaluates <see cref="XPointer"/> pointer and returns /// iterator over pointed nodes. /// </summary> /// <param name="nav">XPathNavigator to evaluate the /// <see cref="XPointer"/> on.</param> /// <returns><see cref="XPathNodeIterator"/> over pointed nodes</returns> public override XPathNodeIterator Evaluate(XPathNavigator nav) { XPathNodeIterator result; XmlNamespaceManager nm = new XmlNamespaceManager(nav.NameTable); for (int i=0; i<_parts.Count; i++) { PointerPart part = _parts[i]; result = part.Evaluate(nav, nm); if (result != null && result.MoveNext()) return result; } throw new NoSubresourcesIdentifiedException(SR.GetString("NoSubresourcesIdentifiedException", _xpointer)); } #endregion } } --- NEW FILE: XmlnsSchemaPointerPart.cs --- #region using using System; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// xmlns() scheme based <see cref="XPointer"/> pointer part. /// </summary> internal class XmlnsSchemaPointerPart : PointerPart { #region private members private string _prefix, _uri; #endregion #region constructors /// <summary> /// Creates xmlns() scheme pointer part with given /// namespace prefix and namespace URI. /// </summary> /// <param name="prefix">Namespace prefix</param> /// <param name="uri">Namespace URI</param> public XmlnsSchemaPointerPart(string prefix, string uri) { _prefix = prefix; _uri = uri; } #endregion #region PointerPart overrides /// <summary> /// Evaluates <see cref="XPointer"/> pointer part and returns pointed nodes. /// </summary> /// <param name="doc">Document to evaluate pointer part on</param> /// <param name="nm">Namespace manager</param> /// <returns>Pointed nodes</returns> public override XPathNodeIterator Evaluate(XPathNavigator doc, XmlNamespaceManager nm) { nm.AddNamespace(_prefix, _uri); return null; } #endregion #region parser public static XmlnsSchemaPointerPart ParseSchemaData(XPointerLexer lexer) { //[1] XmlnsSchemeData ::= NCName S? '=' S? EscapedNamespaceName //[2] EscapedNamespaceName ::= EscapedData* //Read prefix as NCName lexer.NextLexeme(); if (lexer.Kind != XPointerLexer.LexKind.NCName) { Debug.WriteLine(SR.InvalidTokenInXmlnsSchemeWhileNCNameExpected); return null; } string prefix = lexer.NCName; lexer.SkipWhiteSpace(); lexer.NextLexeme(); if (lexer.Kind != XPointerLexer.LexKind.Eq) { Debug.WriteLine(SR.InvalidTokenInXmlnsSchemeWhileEqualsSignExpected); return null; } lexer.SkipWhiteSpace(); string nsURI; try { nsURI = lexer.ParseEscapedData(); } catch (Exception e) { throw new XPointerSyntaxException(SR.GetString("SyntaxErrorInXmlnsSchemeData", e.Message)); } return new XmlnsSchemaPointerPart(prefix, nsURI); } #endregion } } --- NEW FILE: ShorthandPointer.cs --- #region using using System; using System.Xml; using System.Xml.XPath; using Mvp.Xml.Common.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// Shorthand XPointer pointer. /// </summary> internal class ShorthandPointer : Pointer { #region private members private string _NCName; #endregion #region constructors /// <summary> /// Creates shorthand XPointer given bare name. /// </summary> /// <param name="n">Shorthand (bare name)</param> public ShorthandPointer(string n) { _NCName = n; } #endregion #region Pointer overrides /// <summary> /// Evaluates <see cref="XPointer"/> pointer and returns /// iterator over pointed nodes. /// </summary> /// <remarks>Note, that returned XPathNodeIterator is already moved once.</remarks> /// <param name="nav">XPathNavigator to evaluate the /// <see cref="XPointer"/> on.</param> /// <returns><see cref="XPathNodeIterator"/> over pointed nodes</returns> public override XPathNodeIterator Evaluate(XPathNavigator nav) { XPathNodeIterator result = XPathCache.Select("id('"+ _NCName + "')", nav, (XmlNamespaceManager)null); if (result != null && result.MoveNext()) { return result; } else throw new NoSubresourcesIdentifiedException(SR.GetString("NoSubresourcesIdentifiedException", _NCName)); } #endregion } } --- NEW FILE: changelog.txt --- --------------------------------------------------------- October 16, 2005 Ported to .NET 2.0. --------------------------------------------------------- October 11, 2004 Added optional and limited support for schema-determined IDs. --------------------------------------------------------- October 9, 2004 Changed namespace to Mvp.Xml.XPointer. Externalized strings. Did general code review and cleanup. Simplified XPointerReader, switched to XPathDocument. Optimized by using XPathCache and XPathNavigatorReader. --------------------------------------------------------- September 28, 2004 Initial setup. Will contain the project's source code. --- NEW FILE: AssemblyInfo.cs --- using System; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Permissions; [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] [assembly: AssemblyTitle("Mvp.Xml.XPointer")] [assembly: AssemblyDescription("MVP XML Library - XPointer.NET Module")] [assembly: AssemblyVersion("2.0.*")] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../../../../Global/v1/mvp-xml.snk")] [assembly: AssemblyKeyName("")] #region Security Permissions //[assembly: SecurityPermission(SecurityAction.RequestRefuse, UnmanagedCode=true)] #endregion Security Permissions --- NEW FILE: XPath1SchemaPointerPart.cs --- #region using using System; using System.Xml; using System.Xml.XPath; using Mvp.Xml.Common.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// xpath1() scheme based XPointer pointer part. /// </summary> internal class XPath1SchemaPointerPart : PointerPart { #region private members private string _xpath; #endregion #region PointerPart overrides /// <summary> /// Evaluates <see cref="XPointer"/> pointer part and returns pointed nodes. /// </summary> /// <param name="doc">Document to evaluate pointer part on</param> /// <param name="nm">Namespace manager</param> /// <returns>Pointed nodes</returns> public override XPathNodeIterator Evaluate(XPathNavigator doc, XmlNamespaceManager nm) { try { return XPathCache.Select(_xpath, doc, nm); } catch { return null; } } #endregion #region parser public static XPath1SchemaPointerPart ParseSchemaData(XPointerLexer lexer) { XPath1SchemaPointerPart part = new XPath1SchemaPointerPart(); try { part.XPath = lexer.ParseEscapedData(); } catch (Exception e) { throw new XPointerSyntaxException(SR.GetString("SyntaxErrorInXPath1SchemeData", e.Message)); } return part; } #endregion } } --- NEW FILE: SR.resx --- <?xml version="1.0" encoding="utf-8" ?> <root> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:element name="root" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="resheader"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name="ResMimeType"> <value>text/microsoft-resx</value> </resheader> <resheader name="Version"> <value>1.0.0.0</value> </resheader> <resheader name="Reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="Writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name="InvalidTokenInElementSchemeWhileNumberExpected" type="System.String" mimetype="System.String"> <value>Syntax error in element() scheme data: Invalid token in ChildSequence, a number was expected.</value> </data> <data name="ZeroIndexInElementSchemechildSequence" type="System.String" mimetype="System.String"> <value>Syntax error in element() scheme data: 0 index in ChildSequence.</value> </data> <data name="InvalidTokenInElementSchemeWhileClosingRoundBracketExpected" type="System.String" mimetype="System.String"> <value>Syntax error in element() scheme data: Invalid token in ChildSequence, a closing round bracket was expected.</value> </data> <data name="EmptyElementSchemeXPointer" type="System.String" mimetype="System.String"> <value>Syntax error in element() scheme data: empty XPointer.</value> </data> <data name="NoSubresourcesIdentifiedException" type="System.String" mimetype="System.String"> <value>XPointer '{0}' doesn't identify any subresources.</value> </data> <data name="InvalidTokenInXmlnsSchemeWhileNCNameExpected" type="System.String" mimetype="System.String"> <value>Syntax error in xmlns() scheme data: Invalid token in XmlnsSchemaData, NCName was expected.</value> </data> <data name="SyntaxErrorInXmlnsSchemeData" type="System.String" mimetype="System.String"> <value>Syntax error in xmlns() scheme data: {0}</value> </data> <data name="SyntaxErrorInXPath1SchemeData" type="System.String" mimetype="System.String"> <value>Syntax error in xpath1() scheme data: {0}</value> </data> <data name="NullXPointer" type="System.String" mimetype="System.String"> <value>XPointer pointer cannot be null.</value> </data> <data name="CircumflexCharMustBeEscaped" type="System.String" mimetype="System.String"> <value>Circumflex character must be escaped in XPointer.</value> </data> <data name="InvalidNameToken" type="System.String" mimetype="System.String"> <value>Invalid Name token: {0}:{1}.</value> </data> <data name="UnexpectedEndOfSchemeData" type="System.String" mimetype="System.String"> <value>Unexpected end of scheme data.</value> </data> <data name="UndeclaredPrefix" type="System.String" mimetype="System.String"> <value>Undeclared prefix '{0}'.</value> </data> <data name="InvalidTokenAfterShorthandPointer" type="System.String" mimetype="System.String"> <value>Invalid token after shorthand pointer.</value> </data> <data name="InvalidToken" type="System.String" mimetype="System.String"> <value>Invalid token.</value> </data> <data name="SyntaxErrorInXPointerSchemeData" type="System.String" mimetype="System.String"> <value>Syntax error in xpointer() scheme data: {0}</value> </data> </root> --- NEW FILE: XPointerSchema.cs --- #region using using System; using System.Collections.Generic; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// XPointer scheme. /// </summary> internal class XPointerSchema { #region public members public enum SchemaType { Element, Xmlns, XPath1, XPointer, Unknown } public static IDictionary<string, SchemaType> Schemas = CreateSchemasTable(); private static IDictionary<string, SchemaType> CreateSchemasTable() { IDictionary<string, SchemaType> table = new Dictionary<string, SchemaType>(4); //<namespace uri>:<ncname> table.Add(":element", SchemaType.Element); table.Add(":xmlns", SchemaType.Xmlns); table.Add(":xpath1", SchemaType.XPath1); table.Add(":xpointer", SchemaType.XPointer); return table; } #endregion } } --- NEW FILE: ElementSchemaPointerPart.cs --- #region using using System; using System.Xml.XPath; using System.Xml; using System.Text; using Mvp.Xml.Common.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// element() scheme based <see cref="XPointer"/> pointer part. /// </summary> internal class ElementSchemaPointerPart : PointerPart { #region private fields private string _xpath; #endregion #region public members /// <summary> /// Equivalent XPath expression. /// </summary> public string XPath { get { return _xpath; } set { _xpath = value; } } #endregion #region PointerPart overrides /// <summary> /// Evaluates <see cref="XPointer"/> pointer part and returns pointed nodes. /// </summary> /// <param name="doc">Document to evaluate pointer part on</param> /// <param name="nm">Namespace manager</param> /// <returns>Pointed nodes</returns> public override XPathNodeIterator Evaluate(XPathNavigator doc, XmlNamespaceManager nm) { return XPathCache.Select(_xpath, doc, nm); } #endregion #region parser /// <summary> /// Parses element() based pointer part and builds instance of <c>ElementSchemaPointerPart</c> class. /// </summary> /// <param name="lexer">Lexical analizer.</param> /// <returns>Newly created <c>ElementSchemaPointerPart</c> object.</returns> public static ElementSchemaPointerPart ParseSchemaData(XPointerLexer lexer) { //Productions: //[1] ElementSchemeData ::= (NCName ChildSequence?) | ChildSequence //[2] ChildSequence ::= ('/' [1-9] [0-9]*)+ StringBuilder xpathBuilder = new StringBuilder(); ElementSchemaPointerPart part = new ElementSchemaPointerPart(); lexer.NextLexeme(); if (lexer.Kind == XPointerLexer.LexKind.NCName) { xpathBuilder.Append("id('"); xpathBuilder.Append(lexer.NCName); xpathBuilder.Append("')"); lexer.NextLexeme(); } int childSequenceLen = 0; while (lexer.Kind == XPointerLexer.LexKind.Slash) { lexer.NextLexeme(); if (lexer.Kind != XPointerLexer.LexKind.Number) { Debug.WriteLine(SR.InvalidTokenInElementSchemeWhileNumberExpected); return null; } if (lexer.Number == 0) { Debug.WriteLine(SR.ZeroIndexInElementSchemechildSequence); return null; } childSequenceLen++; xpathBuilder.Append("/*["); xpathBuilder.Append(lexer.Number); xpathBuilder.Append("]"); lexer.NextLexeme(); } if (lexer.Kind != XPointerLexer.LexKind.RRBracket) { throw new XPointerSyntaxException(SR.InvalidTokenInElementSchemeWhileClosingRoundBracketExpected); } if (part.NCName==null && childSequenceLen==0) { Debug.WriteLine(SR.EmptyElementSchemeXPointer); return null; } part.XPath = xpathBuilder.ToString(); return part; } #endregion } } --- NEW FILE: XPointerParser.cs --- #region using using System; using System.Collections.Generic; using System.Xml; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// XPointer parser. /// </summary> internal class XPointerParser { #region private members private static IDictionary<string, XPointerSchema.SchemaType> _schemas = XPointerSchema.Schemas; private static XPointerSchema.SchemaType GetSchema(XPointerLexer lexer, IList<PointerPart> parts) { string schemaNSURI; if (lexer.Prefix != String.Empty) { schemaNSURI = null; //resolve prefix for (int i=parts.Count-1; i>=0; i--) { PointerPart part = parts[i]; if (part is XmlnsSchemaPointerPart) { XmlnsSchemaPointerPart xmlnsPart = (XmlnsSchemaPointerPart)part; if (xmlnsPart.Prefix == lexer.Prefix) { schemaNSURI = xmlnsPart.Uri; break; } } } if (schemaNSURI == null) //No binding for the prefix - ignore pointer part return XPointerSchema.SchemaType.Unknown; } else schemaNSURI = String.Empty; XPointerSchema.SchemaType schemaType = _schemas[schemaNSURI + ':' + lexer.NCName]; return schemaType != null ? schemaType : XPointerSchema.SchemaType.Unknown; } #endregion #region public members public static Pointer ParseXPointer(string xpointer) { IList<PointerPart> parts; XPointerLexer lexer; lexer = new XPointerLexer( xpointer); lexer.NextLexeme(); if (lexer.Kind == XPointerLexer.LexKind.NCName && !lexer.CanBeSchemaName) { //Shorthand pointer Pointer ptr = new ShorthandPointer(lexer.NCName); lexer.NextLexeme(); if (lexer.Kind != XPointerLexer.LexKind.Eof) throw new XPointerSyntaxException(SR.InvalidTokenAfterShorthandPointer); return ptr; } else { //SchemaBased pointer parts = new List<PointerPart>(); while (lexer.Kind != XPointerLexer.LexKind.Eof) { if ((lexer.Kind == XPointerLexer.LexKind.NCName || lexer.Kind == XPointerLexer.LexKind.QName) && lexer.CanBeSchemaName) { XPointerSchema.SchemaType schemaType = GetSchema(lexer, parts); //Move to '(' lexer.NextLexeme(); switch (schemaType) { case XPointerSchema.SchemaType.Element: ElementSchemaPointerPart elemPart = ElementSchemaPointerPart.ParseSchemaData(lexer); if (elemPart != null) parts.Add(elemPart); break; case XPointerSchema.SchemaType.Xmlns: XmlnsSchemaPointerPart xmlnsPart = XmlnsSchemaPointerPart.ParseSchemaData(lexer); if (xmlnsPart != null) parts.Add(xmlnsPart); break; case XPointerSchema.SchemaType.XPath1: XPath1SchemaPointerPart xpath1Part = XPath1SchemaPointerPart.ParseSchemaData(lexer); if (xpath1Part != null) parts.Add(xpath1Part); break; case XPointerSchema.SchemaType.XPointer: XPointerSchemaPointerPart xpointerPart = XPointerSchemaPointerPart.ParseSchemaData(lexer); if (xpointerPart != null) parts.Add(xpointerPart); break; default: //Unknown scheme lexer.ParseEscapedData(); break; } //Skip ')' lexer.NextLexeme(); //Skip possible whitespace if (lexer.Kind == XPointerLexer.LexKind.Space) lexer.NextLexeme(); } else throw new XPointerSyntaxException(SR.InvalidToken); } return new SchemaBasedPointer(parts, xpointer); } } #endregion } } --- NEW FILE: XPointerLexer.cs --- #region using using System; using System.Xml; using System.Text; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// XPointer lexical analyzer. /// </summary> internal class XPointerLexer { #region private members private string _ptr; private int _ptrIndex; private LexKind _kind; private char _currChar; private int _number; private string _ncname; private string _prefix; private bool _canBeSchemaName; private string ParseName() { int start = _ptrIndex - 1; int len = 0; while (LexUtils.IsNCNameChar(_currChar)) { NextChar(); len ++; } return _ptr.Substring(start, len); } #endregion #region constructors public XPointerLexer(string p) { if (p == null) throw new ArgumentNullException("pointer", SR.NullXPointer); _ptr = p; NextChar(); } #endregion #region public members public bool NextChar() { if (_ptrIndex < _ptr.Length) { _currChar = _ptr[_ptrIndex++]; return true; } else { _currChar = '\0'; return false; } } public LexKind Kind { get { return _kind; } } public int Number { get { return _number; } } public string NCName { get { return _ncname; } } public string Prefix { get { return _prefix; } } public bool CanBeSchemaName { get { return _canBeSchemaName; } } public void SkipWhiteSpace() { while (LexUtils.IsWhitespace(_currChar)) NextChar(); } public bool NextLexeme() { switch (_currChar) { case '\0' : _kind = LexKind.Eof; return false; case '(': case ')': case '=': case '/': _kind = (LexKind)Convert.ToInt32(_currChar); NextChar(); break; case '^': NextChar(); if (_currChar=='^' || _currChar=='(' || _currChar==')') { _kind = LexKind.EscapedData; NextChar(); } else throw new XPointerSyntaxException(SR.CircumflexCharMustBeEscaped); break; default: if (Char.IsDigit(_currChar)) { _kind = LexKind.Number; int start = _ptrIndex - 1; int len = 0; while (Char.IsDigit(_currChar)) { NextChar(); len ++; } _number = XmlConvert.ToInt32(_ptr.Substring(start, len)); break; } else if (LexUtils.IsStartNameChar(_currChar)) { _kind = LexKind.NCName; _prefix = String.Empty; _ncname = ParseName(); if (_currChar == ':') { //QName? NextChar(); _prefix = _ncname; _kind = LexKind.QName; if (LexUtils.IsStartNCNameChar(_currChar)) _ncname = ParseName(); else throw new XPointerSyntaxException(SR.GetString("InvalidNameToken", _prefix, _currChar)); } _canBeSchemaName = _currChar=='('; break; } else if (LexUtils.IsWhitespace(_currChar)) { _kind = LexKind.Space; while (LexUtils.IsWhitespace(_currChar)) NextChar(); break; } else { _kind = LexKind.EscapedData; break; } } return true; } public string ParseEscapedData() { int depth = 0; StringBuilder sb = new StringBuilder(); while (true) { switch (_currChar) { case '^': if (!NextChar()) throw new XPointerSyntaxException(SR.UnexpectedEndOfSchemeData); else if (_currChar=='^' || _currChar=='(' || _currChar==')') sb.Append(_currChar); else throw new XPointerSyntaxException(SR.CircumflexCharMustBeEscaped); break; case '(': depth++; goto default; case ')': if (depth-- == 0) { //Skip ')' NextLexeme(); return sb.ToString(); } else goto default; default: sb.Append(_currChar); break; } if (!NextChar()) throw new XPointerSyntaxException(SR.UnexpectedEndOfSchemeData); } } public enum LexKind { NCName = 'N', QName = 'Q', LRBracket = '(', RRBracket = ')', Circumflex = '^', Number = 'd', Eq = '=', Space = 'S', Slash = '/', EscapedData = 'D', Eof = 'E' } #endregion } } --- NEW FILE: PointerPart.cs --- #region using using System; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// Part of SchemaBased <see cref="XPointer"/> pointer. /// </summary> internal abstract class PointerPart { #region public methods /// <summary> /// Evaluates <see cref="XPointer"/> pointer part and returns pointed nodes. /// </summary> /// <param name="doc">Document to evaluate pointer part on</param> /// <param name="nm">Namespace manager</param> /// <returns>Pointed nodes</returns> public abstract XPathNodeIterator Evaluate(XPathNavigator doc, XmlNamespaceManager nm); #endregion } } --- NEW FILE: XPointerReader.cs --- #region using using System; using System.Xml; using System.Xml.XPath; using System.Xml.Schema; using System.IO; using System.Collections.Generic; using Mvp.Xml.Common.XPath; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// <c>XPointerReader</c> implements XPointer Framework in /// a fast, non-caching, forward-only way. <c>XPointerReader</c> /// supports XPointer Framework, element(), xmlns(), xpath1() and /// xpointer() (XPath subset only) XPointer schemes. /// </summary> /// <remarks>See <a href="http://mvp-xml.sf.net/xpointer">XPointer.NET homepage</a> for more info.</remarks> /// <author>Oleg Tkachenko, ol...@tk...</author> public class XPointerReader : XmlReader, IHasXPathNavigator { #region private members //Underlying reader private XmlReader _reader; //Nodes selected by xpointer private XPathNodeIterator _pointedNodes; //Document cache private static IDictionary<string, WeakReference> _cache; /// <summary> /// Initializes the <c>XPointerReader</c>. /// </summary> private void Init(XPathNavigator nav, string xpointer) { Pointer pointer = XPointerParser.ParseXPointer(xpointer); _pointedNodes = pointer.Evaluate(nav); //There is always at least one identified node //XPathNodeIterator is already at the first node _reader = new XPathNavigatorReader(_pointedNodes.Current); } private XPathDocument CreateAndCacheDocument(XmlReader r, bool supportSchemaDeterminedIDs) { string uri = r.BaseURI; XmlValidatingReader vr = null; if (supportSchemaDeterminedIDs) { vr = new IdAssuredValidatingReader(r); vr.ValidationType = ValidationType.Auto; } else { vr = new XmlValidatingReader(r); vr.ValidationType = ValidationType.None; } vr.EntityHandling = EntityHandling.ExpandEntities; vr.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(ValidationCallback); XPathDocument doc = new XPathDocument(vr, XmlSpace.Preserve); vr.Close(); lock(_cache) { if (!_cache.ContainsKey(uri)) _cache.Add(uri, new WeakReference(doc)); } return doc; } //Dummy validation even handler private static void ValidationCallback(object sender, ValidationEventArgs args) { //do nothing } #endregion #region constructors /// <summary> /// Creates <c>XPointerReader</c> instnace with given <see cref="IXPathNavigable"/> /// and xpointer. /// </summary> public XPointerReader(IXPathNavigable doc, string xpointer) : this (doc.CreateNavigator(), xpointer) {} /// <summary> /// Creates <c>XPointerReader</c> instnace with given <see cref="XPathNavigator"/> /// and xpointer. /// </summary> public XPointerReader(XPathNavigator nav, string xpointer) { Init(nav, xpointer); } /// <summary> /// Creates <c>XPointerReader</c> instance with given uri and xpointer. /// </summary> public XPointerReader(string uri, string xpointer) : this (new XmlTextReader(uri), xpointer, false) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given uri, nametable and xpointer. /// </summary> public XPointerReader(string uri, XmlNameTable nt, string xpointer) : this (new XmlTextReader(uri, nt), xpointer, false) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given uri, nametable and xpointer. /// Additionally sets a flag whether to support schema-determined IDs. /// </summary> public XPointerReader(string uri, XmlNameTable nt, string xpointer, bool supportSchemaDeterminedIDs) : this (new XmlTextReader(uri, nt), xpointer, supportSchemaDeterminedIDs) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given uri, stream, nametable and xpointer. /// </summary> public XPointerReader(string uri, Stream stream, XmlNameTable nt, string xpointer) : this (uri, stream, nt, xpointer, false) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given uri, stream, nametable and xpointer. /// Additionally sets a flag whether to support schema-determined IDs. /// </summary> public XPointerReader(string uri, Stream stream, XmlNameTable nt, string xpointer, bool supportSchemaDeterminedIDs) : this (new XmlTextReader(uri, stream, nt), xpointer, supportSchemaDeterminedIDs) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given uri, stream and xpointer. /// </summary> public XPointerReader(string uri, Stream stream, string xpointer) : this (uri, stream, new NameTable(), xpointer) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given uri, stream and xpointer. /// Additionally sets a flag whether to support schema-determined IDs. /// </summary> public XPointerReader(string uri, Stream stream, string xpointer, bool supportSchemaDeterminedIDs) : this (uri, stream, new NameTable(), xpointer, supportSchemaDeterminedIDs) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given XmlReader and xpointer. /// Additionally sets a flag whether to support schema-determined IDs. /// </summary> public XPointerReader(XmlReader reader, string xpointer) : this (reader, xpointer, false) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given XmlReader and xpointer. /// Additionally sets a flag whether to support schema-determined IDs. /// </summary> public XPointerReader(XmlReader reader, string xpointer, bool supportSchemaDeterminedIDs) { XPathDocument doc = null; if (_cache == null) _cache = new Dictionary<string, WeakReference>(); WeakReference wr = _cache[reader.BaseURI]; if (wr != null && wr.IsAlive) { doc = (XPathDocument)wr.Target; reader.Close(); } else { //Not cached or GCollected doc = CreateAndCacheDocument(reader, supportSchemaDeterminedIDs); } Init(doc.CreateNavigator(), xpointer); } /// <summary> /// Creates <c>XPointerReader</c> instance with given /// document's URI and content. /// </summary> /// <param name="uri">XML document's base URI</param> /// <param name="content">XML document's content</param> /// <param name="xpointer">XPointer pointer</param> public XPointerReader(string uri, string content, string xpointer) : this(uri, content, xpointer, false) {} /// <summary> /// Creates <c>XPointerReader</c> instance with given /// document's URI and content. /// </summary> /// <param name="uri">XML document's base URI</param> /// <param name="content">XML document's content</param> /// <param name="xpointer">XPointer pointer</param> /// <param name="supportSchemaDeterminedIDs">A flag whether to /// support schema-determined IDs</param> public XPointerReader(string uri, string content, string xpointer, bool supportSchemaDeterminedIDs) { XPathDocument doc = null; if (_cache == null) _cache = new Dictionary<string, WeakReference>(); WeakReference wr = _cache[uri]; if (wr != null && wr.IsAlive) doc = (XPathDocument)wr.Target; else { //Not cached or GCollected XmlTextReader r = new XmlTextReader(uri, new StringReader(content)); doc = CreateAndCacheDocument(r, supportSchemaDeterminedIDs); } Init(doc.CreateNavigator(), xpointer); } #endregion #region XmlReader overrides /// <summary>See <see cref="XmlReader.AttributeCount"/>.</summary> public override int AttributeCount { get { return _reader.AttributeCount; } } /// <summary>See <see cref="XmlReader.BaseURI"/>.</summary> public override string BaseURI { get { return _reader.BaseURI; } } /// <summary>See <see cref="XmlReader.HasValue"/>.</summary> public override bool HasValue { get { return _reader.HasValue; } } /// <summary>See <see cref="XmlReader.IsDefault"/>.</summary> public override bool IsDefault { get { return _reader.IsDefault; } } /// <summary>See <see cref="XmlReader.Name"/>.</summary> public override string Name { get { return _reader.Name; } } /// <summary>See <see cref="XmlReader.LocalName"/>.</summary> public override string LocalName { get { return _reader.LocalName; } } /// <summary>See <see cref="XmlReader.NamespaceURI"/>.</summary> public override string NamespaceURI { get { return _reader.NamespaceURI; } } /// <summary>See <see cref="XmlReader.NameTable"/>.</summary> public override XmlNameTable NameTable { get{ return _reader.NameTable; } } /// <summary>See <see cref="XmlReader.NodeType"/>.</summary> public override XmlNodeType NodeType { get { return _reader.NodeType; } } /// <summary>See <see cref="XmlReader.Prefix"/>.</summary> public override string Prefix { get { return _reader.Prefix; } } /// <summary>See <see cref="XmlReader.QuoteChar"/>.</summary> public override char QuoteChar { get { return _reader.QuoteChar; } } /// <summary>See <see cref="XmlReader.Close"/>.</summary> public override void Close() { if (_reader != null) _reader.Close(); } /// <summary>See <see cref="XmlReader.Depth"/>.</summary> public override int Depth { get { return _reader.Depth; } } /// <summary>See <see cref="XmlReader.EOF"/>.</summary> public override bool EOF { get { return _reader.EOF; } } /// <summary>See <see cref="XmlReader.GetAttribute"/>.</summary> public override string GetAttribute(int i) { return _reader.GetAttribute(i); } /// <summary>See <see cref="XmlReader.GetAttribute"/>.</summary> public override string GetAttribute(string name) { return _reader.GetAttribute(name); } /// <summary>See <see cref="XmlReader.GetAttribute"/>.</summary> public override string GetAttribute(string name, string namespaceURI) { return _reader.GetAttribute(name, namespaceURI); } /// <summary>See <see cref="XmlReader.IsEmptyElement"/>.</summary> public override bool IsEmptyElement { get { return _reader.IsEmptyElement; } } /// <summary>See <see cref="XmlReader.LookupNamespace"/>.</summary> public override String LookupNamespace(String prefix) { return _reader.LookupNamespace(prefix); } /// <summary>See <see cref="XmlReader.MoveToAttribute"/>.</summary> public override void MoveToAttribute(int i) { _reader.MoveToAttribute(i); } /// <summary>See <see cref="XmlReader.MoveToAttribute"/>.</summary> public override bool MoveToAttribute(string name) { return _reader.MoveToAttribute(name); } /// <summary>See <see cref="XmlReader.MoveToAttribute"/>.</summary> public override bool MoveToAttribute(string name, string ns) { return _reader.MoveToAttribute(name, ns); } /// <summary>See <see cref="XmlReader.MoveToElement"/>.</summary> public override bool MoveToElement() { return _reader.MoveToElement(); } /// <summary>See <see cref="XmlReader.MoveToFirstAttribute"/>.</summary> public override bool MoveToFirstAttribute() { return _reader.MoveToFirstAttribute(); } /// <summary>See <see cref="XmlReader.MoveToNextAttribute"/>.</summary> public override bool MoveToNextAttribute() { return _reader.MoveToNextAttribute(); } /// <summary>See <see cref="XmlReader.ReadAttributeValue"/>.</summary> public override bool ReadAttributeValue() { return _reader.ReadAttributeValue(); } /// <summary>See <see cref="XmlReader.ReadState"/>.</summary> public override ReadState ReadState { get { return _reader.ReadState; } } /// <summary>See <see cref="XmlReader.this"/>.</summary> public override String this [int i] { get { return _reader[i]; } } /// <summary>See <see cref="XmlReader.this"/>.</summary> public override string this [string name] { get { return _reader[name]; } } /// <summary>See <see cref="XmlReader.this"/>.</summary> public override string this [string name, string namespaceURI] { get { return _reader[name, namespaceURI]; } } /// <summary>See <see cref="XmlReader.ResolveEntity"/>.</summary> public override void ResolveEntity() { _reader.ResolveEntity(); } /// <summary>See <see cref="XmlReader.XmlLang"/>.</summary> public override string XmlLang { get { return _reader.XmlLang; } } /// <summary>See <see cref="XmlReader.XmlSpace"/>.</summary> public override XmlSpace XmlSpace { get { return _reader.XmlSpace; } } /// <summary>See <see cref="XmlReader.Value"/>.</summary> public override string Value { get { return _reader.Value; } } /// <summary>See <see cref="XmlReader.ReadInnerXml"/>.</summary> public override string ReadInnerXml() { return _reader.ReadInnerXml(); } /// <summary>See <see cref="XmlReader.ReadOuterXml"/>.</summary> public override string ReadOuterXml() { return _reader.ReadOuterXml(); } /// <summary>See <see cref="XmlReader.ReadString"/>.</summary> public override string ReadString() { return _reader.ReadString(); } /// <summary>See <see cref="XmlReader.Read"/>.</summary> public override bool Read() { bool baseRead = _reader.Read(); if (baseRead) return true; else if (_pointedNodes != null) { if (_pointedNodes.MoveNext()) { _reader = _pointedNodes.Current.ReadSubtree(); return _reader.Read(); } } return false; } #endregion #region IHasXPathNavigator Members /// <summary> /// Returns the XPathNavigator for the current context or position. /// </summary> /// <returns></returns> public XPathNavigator GetNavigator() { return _pointedNodes.Current.Clone(); } #endregion } } --- NEW FILE: XPointerException.cs --- #region using using System; #endregion namespace Mvp.Xml.XPointer { /// <summary> /// Generic XPointer exception. /// </summary> public abstract class XPointerException : Exception { /// <summary> /// Initializes a new instance of the <see cref="ApplicationException"/> /// class with a specified error message. /// </summary> /// <param name="message">Error message</param> public XPointerException(string message) : base(message) {} /// <summary> /// Initializes a new instance of the <see cref="ApplicationException"/> /// class with a specified error message and a reference to the /// inner exception that is the cause of this exception. /// </summary> /// <param name="message">Error message</param> /// <param name="innerException">Inner exception</param> public XPointerException(string message, Exception innerException) : base(message, innerException) {} } /// <summary> /// XPointer Framework syntax error. /// </summary> public class XPointerSyntaxException : XPointerException { /// <summary> /// Initializes a new instance of the <see cref="XPointerSyntaxException"/> /// class with a specified error message. /// </summary> /// <param name="message">Error message</param> public XPointerSyntaxException(string message) : base(message) {} /// <summary> /// Initializes a new instance of the <see cref="XPointerSyntaxException"/> /// class with a specified error message and a reference to the /// inner exception that is the cause of this exception. /// </summary> /// <param name="message">Error message</param> /// <param name="innerException">Inner exception</param> public XPointerSyntaxException(string message, Exception innerException) : base(message, innerException) {} } /// <summary> /// XPointer doesn't identify any subresources - it's an error as per /// XPointer Framework. /// </summary> public class NoSubresourcesIdentifiedException : XPointerException { /// <summary> /// Initializes a new instance of the <see cref="NoSubresourcesIdentifiedException"/> /// class with a specified error message. /// </summary> /// <param name="message">Error message</param> public NoSubresourcesIdentifiedException(string message) : base(message) {} /// <summary> /// Initializes a new instance of the <see cref="NoSubresourcesIdentifiedException"/> /// class with a specified error message and a reference to the /// inner exception that is the cause of this exception. /// </summary> /// <param name="message">Error message</param> /// <param name="innerException">Inner exception</param> public NoSubresourcesIdentifiedException(string message, Exception innerException) : base(message, innerException) {} } } --- NEW FILE: XPointer.csproj --- (This appears to be a binary file; contents omitted.) --- NEW FILE: SR.cs --- #region using using System; using System.Resources; using System.Threading; #endregion namespace Mvp.Xml.XPointer { /// <summary>Contains resources for the application.</summary> internal sealed class SR { private static ResourceManager resourceManager = new ResourceManager(typeof(SR).FullName, typeof(SR).Module.Assembly ); private SR() {} /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/>. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <returns>The object resource.</returns> public static object GetObject(string key) { return resourceManager.GetObject(key); } /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/>. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <returns>The string resource.</returns> public static string GetString(string key) { return resourceManager.GetString(key); } /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/> and /// formats it with the arguments received. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <param name='args'>The arguments to format the resource with.</param> /// <returns>The string resource.</returns> internal static string GetString (string key, params object[] args) { return String.Format(GetString(key), args); } /// <summary></summary> public static string InvalidTokenInElementSchemeWhileNumberExpected { get { return SR.GetString("InvalidTokenInElementSchemeWhileNumberExpected"); } } /// <summary></summary> public static string ZeroIndexInElementSchemechildSequence { get { return SR.GetString("ZeroIndexInElementSchemechildSequence"); } } /// <summary></summary> public static string InvalidTokenInElementSchemeWhileClosingRoundBracketExpected { get { return SR.GetString("InvalidTokenInElementSchemeWhileClosingRoundBracketExpected"); } } /// <summary></summary> public static string EmptyElementSchemeXPointer { get { return SR.GetString("EmptyElementSchemeXPointer"); } } /// <summary></summary> public static string InvalidTokenInXmlnsSchemeWhileNCNameExpected { get { return SR.GetString("InvalidTokenInXmlnsSchemeWhileNCNameExpected"); } } /// <summary></summary> pu... [truncated message content] |