/// <summary> /// Creates new instance of <c>XIncludingReader</c> class with /// specified underlying <c>XmlReader</c> reader. /// </summary> /// <param name="reader">Underlying reader to read from</param> public XIncludingReader(XmlReader reader) { XmlTextReader xtr = reader as XmlTextReader; if (xtr != null) { //#pragma warning disable 0618 //XmlValidatingReader vr = new XmlValidatingReader(reader); //vr.ValidationType = ValidationType.None; //vr.EntityHandling = EntityHandling.ExpandEntities; //vr.ValidationEventHandler += new ValidationEventHandler( // ValidationCallback); //_whiteSpaceHandling = xtr.WhitespaceHandling; //_reader = vr; XmlReaderSettings s = new XmlReaderSettings(); s.DtdProcessing = DtdProcessing.Parse; s.ValidationType = ValidationType.None; s.ValidationEventHandler += new ValidationEventHandler( ValidationCallback); if (xtr.WhitespaceHandling == WhitespaceHandling.Significant) { s.IgnoreWhitespace = true; } _reader = XmlReader.Create(reader, s); //#pragma warning restore 0618 } else { _reader = reader; } _nameTable = reader.NameTable; _keywords = new XIncludeKeywords(NameTable); if (_reader.BaseURI != "") _topBaseUri = new Uri(_reader.BaseURI); else { _relativeBaseUri = false; _topBaseUri = new Uri(Assembly.GetExecutingAssembly().Location); } _readers = new Stack<XmlReader>(); _state = XIncludingReaderState.Default; }
/// <summary>See <see cref="XmlReader.MoveToNextAttribute"/></summary> public override bool MoveToNextAttribute() { if (_topLevel) { switch (_state) { case XIncludingReaderState.ExposingXmlBaseAttr: case XIncludingReaderState.ExposingXmlBaseAttrValue: //Exposing xml:base already - switch to xml:lang if (_differentLang) { _state = XIncludingReaderState.ExposingXmlLangAttr; return true; } else { //No need for xml:lang, stop _state = XIncludingReaderState.Default; return false; } case XIncludingReaderState.ExposingXmlLangAttr: case XIncludingReaderState.ExposingXmlLangAttrValue: //Exposing xml:lang already - that's a last one _state = XIncludingReaderState.Default; return false; default: //1+ attrs, default mode bool res = _reader.MoveToNextAttribute(); if (res) { //Still real attributes - it might be xml:base or xml:lang if (_reader.Name == _keywords.XmlBase || _reader.Name == _keywords.XmlLang) //omit them - we expose virtual ones at the end return MoveToNextAttribute(); else return res; } else { //No more attrs - expose virtual xml:base _state = XIncludingReaderState.ExposingXmlBaseAttr; return true; } } } else return _reader.MoveToNextAttribute(); }
/// <summary>See <see cref="XmlReader.Read"/></summary> public override bool Read() { _state = XIncludingReaderState.Default; //Read internal reader bool baseRead = _reader.Read(); if (baseRead) { //If we are including and including reader is at 0 depth - //we are at a top level included item _topLevel = (_readers.Count > 0 && _reader.Depth == 0) ? true : false; if (_topLevel && _reader.NodeType == XmlNodeType.Attribute) //Attempt to include an attribute or namespace node throw new AttributeOrNamespaceInIncludeLocationError(Monobjc.Tools.Sdp.Properties.Resources.AttributeOrNamespaceInIncludeLocationError); if (_topLevel && ((XmlReader)_readers.Peek()).Depth == 0 && _reader.NodeType == XmlNodeType.Element) { if (_gotTopIncludedElem) //Attempt to include more than one element at the top level throw new MalformedXInclusionResultError(Monobjc.Tools.Sdp.Properties.Resources.MalformedXInclusionResult); else _gotTopIncludedElem = true; } if (_topLevel) { //Check if included item has different language _differentLang = AreDifferentLangs(_reader.XmlLang, ((XmlReader)_readers.Peek()).XmlLang); if (_reader.NodeType == XmlNodeType.Element) { //Record real xml:base index _realXmlBaseIndex = -1; int i = 0; while (_reader.MoveToNextAttribute()) { if (_reader.Name == _keywords.XmlBase) { _realXmlBaseIndex = i; break; } i++; } _reader.MoveToElement(); } } switch (_reader.NodeType) { case XmlNodeType.XmlDeclaration: case XmlNodeType.Document: case XmlNodeType.DocumentType: case XmlNodeType.DocumentFragment: //This stuff should not be included into resulting infoset, //but should be inclused into acquired infoset return _readers.Count > 0 ? Read() : baseRead; case XmlNodeType.Element: //Check for xi:include if (IsIncludeElement(_reader)) { //xi:include element found //Save current reader to possible fallback processing XmlReader current = _reader; try { return ProcessIncludeElement(); } catch (FatalException fe) { throw fe; } catch (Exception e) { //Let's be liberal - any exceptions other than fatal one //should be treated as resource error //Console.WriteLine("Resource error has been detected: " + e.Message); //Start fallback processing if (!current.Equals(_reader)) { _reader.Close(); _reader = current; } _prevFallbackState = _fallbackState; return ProcessFallback(_reader.Depth, e); } //No, it's not xi:include, check it for xi:fallback } else if (IsFallbackElement(_reader)) { //Found xi:fallback not child of xi:include IXmlLineInfo li = _reader as IXmlLineInfo; if (li != null && li.HasLineInfo()) { throw new XIncludeSyntaxError(String.Format( CultureInfo.CurrentCulture, Monobjc.Tools.Sdp.Properties.Resources.FallbackNotChildOfIncludeLong, _reader.BaseURI.ToString(), li.LineNumber, li.LinePosition)); } else throw new XIncludeSyntaxError(String.Format( CultureInfo.CurrentCulture, Monobjc.Tools.Sdp.Properties.Resources.FallbackNotChildOfInclude, _reader.BaseURI.ToString())); } else { _gotElement = true; goto default; } case XmlNodeType.EndElement: //Looking for end of xi:fallback if (_fallbackState.Fallbacking && _reader.Depth == _fallbackState.FallbackDepth && IsFallbackElement(_reader)) { //End of fallback processing _fallbackState.FallbackProcessed = true; //Now read other ignored content till </xi:fallback> return ProcessFallback(_reader.Depth - 1, null); } else goto default; default: return baseRead; } } else { //No more input - finish possible xi:include processing if (_topLevel) _topLevel = false; if (_readers.Count > 0) { _reader.Close(); //Pop previous reader _reader = (XmlReader)_readers.Pop(); //Successful include - skip xi:include content if (!_reader.IsEmptyElement) CheckAndSkipContent(); return Read(); } else { if (!_gotElement) throw new MalformedXInclusionResultError(Monobjc.Tools.Sdp.Properties.Resources.MalformedXInclusionResult); //That's all, folks return false; } } }
/// <summary>See <see cref="XmlReader.MoveToFirstAttribute"/></summary> public override bool MoveToFirstAttribute() { if (_topLevel) { bool res = _reader.MoveToFirstAttribute(); if (res) { //it might be xml:base or xml:lang if (_reader.Name == _keywords.XmlBase || _reader.Name == _keywords.XmlLang) //omit them - we expose virtual ones at the end return MoveToNextAttribute(); else return res; } else { //No attrs? Expose xml:base _state = XIncludingReaderState.ExposingXmlBaseAttr; return true; } } else return _reader.MoveToFirstAttribute(); }
/// <summary>See <see cref="XmlReader.MoveToAttribute(string, string)"/></summary> public override bool MoveToAttribute(string name, string ns) { if (_topLevel) { if (XIncludeKeywords.Equals(name, _keywords.Base) && XIncludeKeywords.Equals(ns, _keywords.XmlNamespace)) { _state = XIncludingReaderState.ExposingXmlBaseAttr; return true; } else if (XIncludeKeywords.Equals(name, _keywords.Lang) && XIncludeKeywords.Equals(ns, _keywords.XmlNamespace)) { _state = XIncludingReaderState.ExposingXmlLangAttr; return true; } } return _reader.MoveToAttribute(name, ns); }
/// <summary>See <see cref="XmlReader.MoveToAttribute(int)"/></summary> public override void MoveToAttribute(int i) { if (_topLevel) { if (i >= _reader.AttributeCount || i == _realXmlBaseIndex) { _state = XIncludingReaderState.ExposingXmlBaseAttr; } else { _reader.MoveToAttribute(i); } } else { _reader.MoveToAttribute(i); } }
/// <summary>See <see cref="XmlReader.ReadAttributeValue"/></summary> public override bool ReadAttributeValue() { switch (_state) { case XIncludingReaderState.ExposingXmlBaseAttr: _state = XIncludingReaderState.ExposingXmlBaseAttrValue; return true; case XIncludingReaderState.ExposingXmlBaseAttrValue: return false; case XIncludingReaderState.ExposingXmlLangAttr: _state = XIncludingReaderState.ExposingXmlLangAttrValue; return true; case XIncludingReaderState.ExposingXmlLangAttrValue: return false; default: return _reader.ReadAttributeValue(); } }
/// <summary> /// Creates new instance of <c>XIncludingReader</c> class with /// specified underlying <c>XmlReader</c> reader. /// </summary> /// <param name="reader">Underlying reader to read from</param> public XIncludingReader(XmlReader reader) { XmlTextReader xtr = reader as XmlTextReader; if (xtr != null) { XmlValidatingReader vr = new XmlValidatingReader(reader); vr.ValidationType = ValidationType.None; vr.EntityHandling = EntityHandling.ExpandEntities; vr.ValidationEventHandler += new ValidationEventHandler( ValidationCallback); _normalization = xtr.Normalization; _whiteSpaceHandling = xtr.WhitespaceHandling; _reader = vr; } else { _reader = reader; } _nameTable = reader.NameTable; _keywords = new XIncludeKeywords(NameTable); if (_reader.BaseURI != "") _topBaseUri = new Uri(_reader.BaseURI); else { _relativeBaseUri = false; _topBaseUri = new Uri(Assembly.GetExecutingAssembly().Location); } _readers = new Stack<XmlReader>(); _state = XIncludingReaderState.Default; }