예제 #1
0
        /// <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;
                }
            }
        }
예제 #2
0
 /// <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,
                             Monobjc.Tools.Sdp.Properties.Resources.IncludeChildOfIncludeLong,
                             BaseURI.ToString(),
                             li.LineNumber, li.LinePosition));
                     }
                     else
                         throw new XIncludeSyntaxError(String.Format(
                             CultureInfo.CurrentCulture,
                             Monobjc.Tools.Sdp.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,
                                 Monobjc.Tools.Sdp.Properties.Resources.TwoFallbacksLong,
                                 BaseURI.ToString(),
                                 li.LineNumber, li.LinePosition));
                         }
                         else
                             throw new XIncludeSyntaxError(String.Format(
                                 CultureInfo.CurrentCulture, Monobjc.Tools.Sdp.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();
     }
 }