internal ValidatingReaderNodeData RecordTextNode(string textValue, string originalStringValue, int depth, int lineNo, int linePos) { ValidatingReaderNodeData textNode = AddContent(XmlNodeType.Text); textNode.SetItemData(textValue, originalStringValue); textNode.SetLineInfo(lineNo, linePos); textNode.Depth = depth; return(textNode); }
internal void RecordEndElementNode() { ValidatingReaderNodeData recordedNode = AddContent(XmlNodeType.EndElement); Debug.Assert(_coreReader.NodeType == XmlNodeType.EndElement || (_coreReader.NodeType == XmlNodeType.Element && _coreReader.IsEmptyElement)); recordedNode.SetItemData(_coreReader.LocalName, _coreReader.Prefix, _coreReader.NamespaceURI, _coreReader.Depth); recordedNode.SetLineInfo(_coreReader as IXmlLineInfo); if (_coreReader.IsEmptyElement) { //Simulated endElement node for <e/>, the coreReader is on cached Element node itself. _readAhead = true; } }
private void Init() { _coreReaderNameTable = _coreReader.NameTable; _cacheState = CachingReaderState.Init; _contentIndex = 0; _currentAttrIndex = -1; _currentContentIndex = -1; _attributeCount = 0; _cachedNode = null; _readAhead = false; //Initialize the cachingReader with start state if (_coreReader.NodeType == XmlNodeType.Element) { ValidatingReaderNodeData element = AddContent(_coreReader.NodeType); element.SetItemData(_coreReader.LocalName, _coreReader.Prefix, _coreReader.NamespaceURI, _coreReader.Depth); //Only created for element node type element.SetLineInfo(_lineInfo); RecordAttributes(); } }
// Reads the next node from the stream/TextReader. public override async Task <bool> ReadAsync() { switch (_cacheState) { case CachingReaderState.Init: _cacheState = CachingReaderState.Record; goto case CachingReaderState.Record; case CachingReaderState.Record: ValidatingReaderNodeData recordedNode = null; if (await _coreReader.ReadAsync().ConfigureAwait(false)) { switch (_coreReader.NodeType) { case XmlNodeType.Element: //Dont record element within the content of a union type since the main reader will break on this and the underlying coreReader will be positioned on this node _cacheState = CachingReaderState.ReaderClosed; return(false); case XmlNodeType.EndElement: recordedNode = AddContent(_coreReader.NodeType); recordedNode.SetItemData(_coreReader.LocalName, _coreReader.Prefix, _coreReader.NamespaceURI, _coreReader.Depth); //Only created for element node type recordedNode.SetLineInfo(_lineInfo); break; case XmlNodeType.Comment: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: recordedNode = AddContent(_coreReader.NodeType); recordedNode.SetItemData(await _coreReader.GetValueAsync().ConfigureAwait(false)); recordedNode.SetLineInfo(_lineInfo); recordedNode.Depth = _coreReader.Depth; break; default: break; } _cachedNode = recordedNode; return(true); } else { _cacheState = CachingReaderState.ReaderClosed; return(false); } case CachingReaderState.Replay: if (_currentContentIndex >= _contentIndex) { //When positioned on the last cached node, switch back as the underlying coreReader is still positioned on this node _cacheState = CachingReaderState.ReaderClosed; _cacheHandler(this); if (_coreReader.NodeType != XmlNodeType.Element || _readAhead) { //Only when coreReader not positioned on Element node, read ahead, otherwise it is on the next element node already, since this was not cached return(await _coreReader.ReadAsync().ConfigureAwait(false)); } return(true); } _cachedNode = _contentEvents[_currentContentIndex]; if (_currentContentIndex > 0) { ClearAttributesInfo(); } _currentContentIndex++; return(true); default: return(false); } }