/// <summary> /// Must be called when an element node's children have been fully enumerated. /// </summary> public void WriteEndElement(bool allowShortcutTag) { XPathNodeRef nodeRef; Debug.Assert(_pageParent != null && _pageParent[_idxParent].NodeType == XPathNodeType.Element); // If element has no content-typed children except for the one about to be added, then // its value is the same as its only text child's. if (!_pageParent[_idxParent].HasContentChild) { switch (_textBldr.TextType) { case TextBlockType.Text: // Collapsed text node can be created if text line number information can be encoded efficiently in parent node if (_lineInfo != null) { // If collapsed text node is not on same line as parent, don't collapse text if (_textBldr.LineNumber != _pageParent[_idxParent].LineNumber) { goto case TextBlockType.Whitespace; } // If position is not within 256 of parent, don't collapse text int posDiff = _textBldr.LinePosition - _pageParent[_idxParent].LinePosition; if (posDiff < 0 || posDiff > XPathNode.MaxCollapsedPositionOffset) { goto case TextBlockType.Whitespace; } // Set collapsed node line position offset _pageParent[_idxParent].SetCollapsedLineInfoOffset(posDiff); } // Set collapsed node text _pageParent[_idxParent].SetCollapsedValue(_textBldr.ReadText()); break; case TextBlockType.SignificantWhitespace: case TextBlockType.Whitespace: // Create separate whitespace node CachedTextNode(); _pageParent[_idxParent].SetValue(_pageSibling[_idxSibling].Value); break; default: // Empty value, so don't create collapsed text node _pageParent[_idxParent].SetEmptyValue(allowShortcutTag); break; } } else { if (_textBldr.HasText) { // Element's last child (one of several) is a text or whitespace node CachedTextNode(); } } // If namespaces were added to this element, if (_pageParent[_idxParent].HasNamespaceDecls) { // Add it to the document's element --> namespace mapping _doc.AddNamespace(_pageParent, _idxParent, _pageNmsp, _idxNmsp); // Restore the previous namespace chain nodeRef = _stkNmsp.Pop(); _pageNmsp = nodeRef.Page; _idxNmsp = nodeRef.Index; } // Make parent of this element the current element _pageSibling = _pageParent; _idxSibling = _idxParent; _idxParent = _pageParent[_idxParent].GetParent(out _pageParent); }