コード例 #1
0
ファイル: XIncludingReader.cs プロジェクト: kisflying/kion
		/// <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(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(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,
									Properties.Resources.FallbackNotChildOfIncludeLong,
									_reader.BaseURI.ToString(), li.LineNumber,
									li.LinePosition));
							}
							else
								throw new XIncludeSyntaxError(String.Format(
									CultureInfo.CurrentCulture,
									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(Properties.Resources.MalformedXInclusionResult);
					//That's all, folks
					return false;
				}
			}
		} // Read()
コード例 #2
0
ファイル: XIncludingReader.cs プロジェクト: kisflying/kion
		/// <summary>
		/// Fallback processing.
		/// </summary>
		/// <param name="depth"><c>xi:include</c> depth level.</param>    
		/// <param name="e">Resource error, which caused this processing.</param>
		/// <remarks>When inluding fails due to any resource error, <c>xi:inlcude</c> 
		/// element content is processed as follows: each child <c>xi:include</c> - 
		/// fatal error, more than one child <c>xi:fallback</c> - fatal error. No 
		/// <c>xi:fallback</c> - the resource error results in a fatal error.
		/// Content of first <c>xi:fallback</c> element is included in a usual way.</remarks>
		private bool ProcessFallback(int depth, Exception e)
		{
			//Read to the xi:include end tag
			while (_reader.Read() && depth < _reader.Depth)
			{
				switch (_reader.NodeType)
				{
					case XmlNodeType.Element:
						if (IsIncludeElement(_reader))
						{
							//xi:include child of xi:include - fatal error
							IXmlLineInfo li = _reader as IXmlLineInfo;
							if (li != null && li.HasLineInfo())
							{
								throw new XIncludeSyntaxError(String.Format(
									CultureInfo.CurrentCulture,
									Properties.Resources.IncludeChildOfIncludeLong,
									BaseURI.ToString(),
									li.LineNumber, li.LinePosition));
							}
							else
								throw new XIncludeSyntaxError(String.Format(
									CultureInfo.CurrentCulture,
									Properties.Resources.IncludeChildOfInclude,
									BaseURI.ToString()));
						}
						if (IsFallbackElement(_reader))
						{
							//Found xi:fallback
							if (_fallbackState.FallbackProcessed)
							{
								IXmlLineInfo li = _reader as IXmlLineInfo;
								if (li != null && li.HasLineInfo())
								{
									//Two xi:fallback                                 
									throw new XIncludeSyntaxError(String.Format(
										CultureInfo.CurrentCulture,
										Properties.Resources.TwoFallbacksLong,
										BaseURI.ToString(),
										li.LineNumber, li.LinePosition));
								}
								else
									throw new XIncludeSyntaxError(String.Format(
										CultureInfo.CurrentCulture, Properties.Resources.TwoFallbacks, BaseURI.ToString()));
							}
							if (_reader.IsEmptyElement)
							{
								//Empty xi:fallback - nothing to include
								_fallbackState.FallbackProcessed = true;
								break;
							}
							_fallbackState.Fallbacking = true;
							_fallbackState.FallbackDepth = _reader.Depth;
							return Read();
						}
						else
							//Ignore anything else along with its content
							SkipContent();
						break;
					default:
						break;
				}
			}
			//xi:include content is read
			if (!_fallbackState.FallbackProcessed)
				//No xi:fallback, fatal error
				throw new FatalResourceException(e);
			else
			{
				//End of xi:include content processing, reset and go forth
				_fallbackState = _prevFallbackState;
				return Read();
			}
		}