/// <summary> /// Override Read in order to search for strippable whitespace, to concatenate adjacent text nodes, and to /// resolve entities. /// </summary> public override bool Read() { string?ws = null; // Clear text value _val = null; while (base.Read()) { switch (base.NodeType) { case XmlNodeType.Element: // Push boolean indicating whether whitespace children of this element should be stripped if (!base.IsEmptyElement) { _stkStrip.PushBit(_shouldStrip); // Strip if rules say we should and we're not within the scope of xml:space="preserve" _shouldStrip = _wsRules.ShouldStripSpace(base.LocalName, base.NamespaceURI) && (base.XmlSpace != XmlSpace.Preserve); } break; case XmlNodeType.EndElement: // Restore parent shouldStrip setting _shouldStrip = _stkStrip.PopBit(); break; case XmlNodeType.Text: case XmlNodeType.CDATA: // If preserving adjacent text, don't perform any further checks if (_preserveAdjacent) { return(true); } if (_shouldStrip) { // Reader may report whitespace as Text or CDATA if (XmlCharType.IsOnlyWhitespace(base.Value)) { goto case XmlNodeType.Whitespace; } // If whitespace was cached, then prepend it to text or CDATA value if (ws != null) { _val = string.Concat(ws, base.Value); } // Preserve adjacent whitespace _preserveAdjacent = true; return(true); } break; case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: // If preserving adjacent text, don't perform any further checks if (_preserveAdjacent) { return(true); } if (_shouldStrip) { // Save whitespace until it can be determined whether it will be stripped ws = ws == null ? base.Value : string.Concat(ws, base.Value); // Read next event continue; } break; case XmlNodeType.EndEntity: // Read next event continue; } // No longer preserve adjacent space _preserveAdjacent = false; return(true); } return(false); }