// // Copy a single XML node, attempting to preserve whitespace. // A side effect of this method is to advance the reader to the next node. // // PERFORMANCE NOTE: this function is used at runtime to copy a configuration section, // and at designtime to copy an entire XML document. // // At designtime, this function needs to be able to copy a <!DOCTYPE declaration. // Copying a <!DOCTYPE declaration is expensive, because due to limitations of the // XmlReader API, we must track the position of the writer to accurately format it. // Tracking the position of the writer is expensive, as it requires examining every // character that is written for newline characters, and maintaining the seek position // of the underlying stream at each new line, which in turn requires a stream flush. // // This function must NEVER require tracking the writer position to copy the Xml nodes // that are used in a configuration section. // internal bool CopyXmlNode(XmlUtilWriter utilWriter) { // // For nodes that have a closing string, such as "<element >" // the XmlReader API does not give us the location of the closing string, e.g. ">". // To correctly determine the location of the closing part, we advance the reader, // determine the position of the next node, then work backwards to add whitespace // and add the closing string. // string close = null; int lineNumber = -1; int linePosition = -1; int readerLineNumber = 0; int readerLinePosition = 0; int writerLineNumber = 0; int writerLinePosition = 0; if (utilWriter.TrackPosition) { readerLineNumber = _reader.LineNumber; readerLinePosition = _reader.LinePosition; writerLineNumber = utilWriter.LineNumber; writerLinePosition = utilWriter.LinePosition; } // We test the node type in the likely order of decreasing occurrence. XmlNodeType nodeType = _reader.NodeType; if (nodeType == XmlNodeType.Whitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.Element) { close = (_reader.IsEmptyElement) ? "/>" : ">"; // get the line position after the element declaration: // <element attr="value" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(_reader.Name); // // Note that there is no way to get spacing between attribute name and value // For example: // // <elem attr="value" /> // // is reported with the same position as // // <elem attr = "value" /> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <element attr="value" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } } else if (nodeType == XmlNodeType.EndElement) { close = ">"; // get line position after the end element declaration: // </element > // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(_reader.Name); } else if (nodeType == XmlNodeType.Comment) { utilWriter.AppendComment(_reader.Value); } else if (nodeType == XmlNodeType.Text) { utilWriter.AppendEscapeTextString(_reader.Value); } else if (nodeType == XmlNodeType.XmlDeclaration) { close = "?>"; // get line position after the xml declaration: // <?xml version="1.0" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + 3; utilWriter.Write("<?xml"); // // Note that there is no way to get spacing between attribute name and value // For example: // // <?xml attr="value" ?> // // is reported with the same position as // // <?xml attr = "value" ?> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <?xml version="1.0" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } // Position reader at beginning of node _reader.MoveToElement(); } else if (nodeType == XmlNodeType.SignificantWhitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.ProcessingInstruction) { // // Note that there is no way to get spacing between attribute name and value // For example: // // <?pi "value" ?> // // is reported with the same position as // // <?pi "value" ?> // // The first example has one space between 'pi' and "value", the second has multiple spaces. // utilWriter.AppendProcessingInstruction(_reader.Name, _reader.Value); } else if (nodeType == XmlNodeType.EntityReference) { utilWriter.AppendEntityRef(_reader.Name); } else if (nodeType == XmlNodeType.CDATA) { utilWriter.AppendCData(_reader.Value); } else if (nodeType == XmlNodeType.DocumentType) { // // XmlNodeType.DocumentType has the following format: // // <!DOCTYPE rootElementName {(SYSTEM uriRef)|(PUBLIC id uriRef)} {[ dtdDecls ]} > // // The reader only gives us the position of 'rootElementName', so we must track what was // written before "<!DOCTYPE" in order to correctly determine the position of the // <!DOCTYPE tag // Debug.Assert(utilWriter.TrackPosition, "utilWriter.TrackPosition"); int c = utilWriter.Write("<!DOCTYPE"); // Write the space between <!DOCTYPE and the rootElementName utilWriter.AppendRequiredWhiteSpace(_lastLineNumber, _lastLinePosition + c, _reader.LineNumber, _reader.LinePosition); // Write the rootElementName utilWriter.Write(_reader.Name); // Get the dtd declarations, if any string dtdValue = null; if (_reader.HasValue) { dtdValue = _reader.Value; } // get line position after the !DOCTYPE declaration: // <!DOCTYPE rootElement SYSTEM rootElementDtdUri > // ^ // linePosition lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; // Note that there is no way to get the spacing after PUBLIC or SYSTEM attributes and their values if (_reader.MoveToFirstAttribute()) { // Write the space before SYSTEM or PUBLIC utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, _reader.LineNumber, _reader.LinePosition); // Write SYSTEM or PUBLIC and the 1st value of the attribute string attrName = _reader.Name; utilWriter.Write(attrName); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(0); // If PUBLIC, write the second value of the attribute if (attrName == "PUBLIC") { _reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(1); } } // If there is a dtd, write it if (dtdValue != null && dtdValue.Length > 0) { utilWriter.Write(" ["); utilWriter.Write(dtdValue); utilWriter.Write(']'); } utilWriter.Write('>'); } // Advance the _reader so we can get the position of the next node. bool moreToRead = _reader.Read(); nodeType = _reader.NodeType; // Close the node we are copying. if (close != null) { // // Find the position of the close string, for example: // // <element > <subElement /> // ^ // closeLinePosition // int startOffset = GetPositionOffset(nodeType); int closeLineNumber = _reader.LineNumber; int closeLinePosition = _reader.LinePosition - startOffset - close.Length; // Add whitespace up to the position of the close string utilWriter.AppendWhiteSpace(lineNumber, linePosition, closeLineNumber, closeLinePosition); // Write the close string utilWriter.Write(close); } // // Track the position of the reader based on the position of the reader // before we copied this node and what we have written in copying the node. // This allows us to determine the position of the <!DOCTYPE tag. // if (utilWriter.TrackPosition) { _lastLineNumber = (readerLineNumber - writerLineNumber) + utilWriter.LineNumber; if (writerLineNumber == utilWriter.LineNumber) { _lastLinePosition = (readerLinePosition - writerLinePosition) + utilWriter.LinePosition; } else { _lastLinePosition = utilWriter.LinePosition; } } return moreToRead; }
// // Copy a single XML node, attempting to preserve whitespace. // A side effect of this method is to advance the reader to the next node. // // PERFORMANCE NOTE: this function is used at runtime to copy a configuration section, // and at designtime to copy an entire XML document. // // At designtime, this function needs to be able to copy a <!DOCTYPE declaration. // Copying a <!DOCTYPE declaration is expensive, because due to limitations of the // XmlReader API, we must track the position of the writer to accurately format it. // Tracking the position of the writer is expensive, as it requires examining every // character that is written for newline characters, and maintaining the seek position // of the underlying stream at each new line, which in turn requires a stream flush. // // This function must NEVER require tracking the writer position to copy the Xml nodes // that are used in a configuration section. // internal bool CopyXmlNode(XmlUtilWriter utilWriter) { // // For nodes that have a closing string, such as "<element >" // the XmlReader API does not give us the location of the closing string, e.g. ">". // To correctly determine the location of the closing part, we advance the reader, // determine the position of the next node, then work backwards to add whitespace // and add the closing string. // string close = null; int lineNumber = -1; int linePosition = -1; int readerLineNumber = 0; int readerLinePosition = 0; int writerLineNumber = 0; int writerLinePosition = 0; if (utilWriter.TrackPosition) { readerLineNumber = _reader.LineNumber; readerLinePosition = _reader.LinePosition; writerLineNumber = utilWriter.LineNumber; writerLinePosition = utilWriter.LinePosition; } // We test the node type in the likely order of decreasing occurrence. XmlNodeType nodeType = _reader.NodeType; if (nodeType == XmlNodeType.Whitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.Element) { close = (_reader.IsEmptyElement) ? "/>" : ">"; // get the line position after the element declaration: // <element attr="value" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(_reader.Name); // // Note that there is no way to get spacing between attribute name and value // For example: // // <elem attr="value" /> // // is reported with the same position as // // <elem attr = "value" /> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <element attr="value" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } } else if (nodeType == XmlNodeType.EndElement) { close = ">"; // get line position after the end element declaration: // </element > // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(_reader.Name); } else if (nodeType == XmlNodeType.Comment) { utilWriter.AppendComment(_reader.Value); } else if (nodeType == XmlNodeType.Text) { utilWriter.AppendEscapeTextString(_reader.Value); } else if (nodeType == XmlNodeType.XmlDeclaration) { close = "?>"; // get line position after the xml declaration: // <?xml version="1.0" // ^ // linePosition // lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + 3; utilWriter.Write("<?xml"); // // Note that there is no way to get spacing between attribute name and value // For example: // // <?xml attr="value" ?> // // is reported with the same position as // // <?xml attr = "value" ?> // // The first example has no spaces around '=', the second example does. // while (_reader.MoveToNextAttribute()) { // get line position of the attribute declaration // <?xml version="1.0" // ^ // attrLinePosition // int attrLineNumber = _reader.LineNumber; int attrLinePosition = _reader.LinePosition; // Write the whitespace before the attribute utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, attrLineNumber, attrLinePosition); // Write the attribute and value int charactersWritten = utilWriter.Write(_reader.Name); charactersWritten += utilWriter.Write('='); charactersWritten += utilWriter.AppendAttributeValue(_reader); // Update position. Note that the attribute value is escaped to always be on a single line. lineNumber = attrLineNumber; linePosition = attrLinePosition + charactersWritten; } // Position reader at beginning of node _reader.MoveToElement(); } else if (nodeType == XmlNodeType.SignificantWhitespace) { utilWriter.Write(_reader.Value); } else if (nodeType == XmlNodeType.ProcessingInstruction) { // // Note that there is no way to get spacing between attribute name and value // For example: // // <?pi "value" ?> // // is reported with the same position as // // <?pi "value" ?> // // The first example has one space between 'pi' and "value", the second has multiple spaces. // utilWriter.AppendProcessingInstruction(_reader.Name, _reader.Value); } else if (nodeType == XmlNodeType.EntityReference) { utilWriter.AppendEntityRef(_reader.Name); } else if (nodeType == XmlNodeType.CDATA) { utilWriter.AppendCData(_reader.Value); } else if (nodeType == XmlNodeType.DocumentType) { // // XmlNodeType.DocumentType has the following format: // // <!DOCTYPE rootElementName {(SYSTEM uriRef)|(PUBLIC id uriRef)} {[ dtdDecls ]} > // // The reader only gives us the position of 'rootElementName', so we must track what was // written before "<!DOCTYPE" in order to correctly determine the position of the // <!DOCTYPE tag // Debug.Assert(utilWriter.TrackPosition, "utilWriter.TrackPosition"); int c = utilWriter.Write("<!DOCTYPE"); // Write the space between <!DOCTYPE and the rootElementName utilWriter.AppendRequiredWhiteSpace(_lastLineNumber, _lastLinePosition + c, _reader.LineNumber, _reader.LinePosition); // Write the rootElementName utilWriter.Write(_reader.Name); // Get the dtd declarations, if any string dtdValue = null; if (_reader.HasValue) { dtdValue = _reader.Value; } // get line position after the !DOCTYPE declaration: // <!DOCTYPE rootElement SYSTEM rootElementDtdUri > // ^ // linePosition lineNumber = _reader.LineNumber; linePosition = _reader.LinePosition + _reader.Name.Length; // Note that there is no way to get the spacing after PUBLIC or SYSTEM attributes and their values if (_reader.MoveToFirstAttribute()) { // Write the space before SYSTEM or PUBLIC utilWriter.AppendRequiredWhiteSpace(lineNumber, linePosition, _reader.LineNumber, _reader.LinePosition); // Write SYSTEM or PUBLIC and the 1st value of the attribute string attrName = _reader.Name; utilWriter.Write(attrName); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(0); // If PUBLIC, write the second value of the attribute if (attrName == "PUBLIC") { _reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(_reader); _reader.MoveToAttribute(1); } } // If there is a dtd, write it if (dtdValue != null && dtdValue.Length > 0) { utilWriter.Write(" ["); utilWriter.Write(dtdValue); utilWriter.Write(']'); } utilWriter.Write('>'); } // Advance the _reader so we can get the position of the next node. bool moreToRead = _reader.Read(); nodeType = _reader.NodeType; // Close the node we are copying. if (close != null) { // // Find the position of the close string, for example: // // <element > <subElement /> // ^ // closeLinePosition // int startOffset = GetPositionOffset(nodeType); int closeLineNumber = _reader.LineNumber; int closeLinePosition = _reader.LinePosition - startOffset - close.Length; // Add whitespace up to the position of the close string utilWriter.AppendWhiteSpace(lineNumber, linePosition, closeLineNumber, closeLinePosition); // Write the close string utilWriter.Write(close); } // // Track the position of the reader based on the position of the reader // before we copied this node and what we have written in copying the node. // This allows us to determine the position of the <!DOCTYPE tag. // if (utilWriter.TrackPosition) { _lastLineNumber = (readerLineNumber - writerLineNumber) + utilWriter.LineNumber; if (writerLineNumber == utilWriter.LineNumber) { _lastLinePosition = (readerLinePosition - writerLinePosition) + utilWriter.LinePosition; } else { _lastLinePosition = utilWriter.LinePosition; } } return(moreToRead); }
// Format an Xml element to be written to the config file. // Params: // xmlElement - the element // linePosition - start position of the element // indent - indent for each depth // skipFirstIndent - skip indent for the first element? // static internal string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter stringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture); XmlUtilWriter utilWriter = new XmlUtilWriter(stringWriter, false); // append newline before indent? bool newLine = false; // last node visited was text? bool lastWasText = false; // width of line from end of indentation int lineWidth; // length of the stringbuilder after last indent with newline int sbLengthLastNewLine = 0; while (reader.Read()) { XmlNodeType nodeType = reader.NodeType; if (lastWasText) { utilWriter.Flush(); lineWidth = sbLengthLastNewLine - ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { lineWidth = 0; } switch (nodeType) { case XmlNodeType.CDATA: case XmlNodeType.Element: case XmlNodeType.EndElement: case XmlNodeType.Comment: // Do not indent if the last node was text - doing so would add whitespace // that is included as part of the text. if (!skipFirstIndent && !lastWasText) { utilWriter.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } } break; default: break; } lastWasText = false; switch (nodeType) { case XmlNodeType.Whitespace: break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(reader.Value); break; case XmlNodeType.CDATA: utilWriter.AppendCData(reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(reader.Name, reader.Value); break; case XmlNodeType.Comment: utilWriter.AppendComment(reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(reader.Value); lastWasText = true; break; case XmlNodeType.Element: { // Write "<elem" utilWriter.Write('<'); utilWriter.Write(reader.Name); lineWidth += reader.Name.Length + 2; int c = reader.AttributeCount; for (int i = 0; i < c; i++) { // Add new line if we've exceeded the line width bool writeSpace; if (lineWidth > MAX_LINE_WIDTH) { utilWriter.AppendIndent(linePosition, indent, reader.Depth - 1, true); lineWidth = indent; writeSpace = false; utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { writeSpace = true; } // Write the attribute reader.MoveToNextAttribute(); utilWriter.Flush(); int startLength = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; if (writeSpace) { utilWriter.AppendSpace(); } utilWriter.Write(reader.Name); utilWriter.Write('='); utilWriter.AppendAttributeValue(reader); utilWriter.Flush(); lineWidth += ((StringWriter)utilWriter.Writer).GetStringBuilder().Length - startLength; } } // position reader back on element reader.MoveToElement(); // write closing tag if (reader.IsEmptyElement) { utilWriter.Write(" />"); } else { utilWriter.Write('>'); } break; case XmlNodeType.EndElement: utilWriter.Write("</"); utilWriter.Write(reader.Name); utilWriter.Write('>'); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(reader.Name); break; // Ignore <?xml and <!DOCTYPE nodes case XmlNodeType.XmlDeclaration: case XmlNodeType.DocumentType: default: break; } // put each new element on a new line newLine = true; // do not skip any more indents skipFirstIndent = false; } utilWriter.Flush(); string s = ((StringWriter)utilWriter.Writer).ToString(); return s; }
// Format an Xml element to be written to the config file. // Params: // xmlElement - the element // linePosition - start position of the element // indent - indent for each depth // skipFirstIndent - skip indent for the first element? // static internal string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter stringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture); XmlUtilWriter utilWriter = new XmlUtilWriter(stringWriter, false); // append newline before indent? bool newLine = false; // last node visited was text? bool lastWasText = false; // width of line from end of indentation int lineWidth; // length of the stringbuilder after last indent with newline int sbLengthLastNewLine = 0; while (reader.Read()) { XmlNodeType nodeType = reader.NodeType; if (lastWasText) { utilWriter.Flush(); lineWidth = sbLengthLastNewLine - ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { lineWidth = 0; } switch (nodeType) { case XmlNodeType.CDATA: case XmlNodeType.Element: case XmlNodeType.EndElement: case XmlNodeType.Comment: // Do not indent if the last node was text - doing so would add whitespace // that is included as part of the text. if (!skipFirstIndent && !lastWasText) { utilWriter.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } } break; default: break; } lastWasText = false; switch (nodeType) { case XmlNodeType.Whitespace: break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(reader.Value); break; case XmlNodeType.CDATA: utilWriter.AppendCData(reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(reader.Name, reader.Value); break; case XmlNodeType.Comment: utilWriter.AppendComment(reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(reader.Value); lastWasText = true; break; case XmlNodeType.Element: { // Write "<elem" utilWriter.Write('<'); utilWriter.Write(reader.Name); lineWidth += reader.Name.Length + 2; int c = reader.AttributeCount; for (int i = 0; i < c; i++) { // Add new line if we've exceeded the line width bool writeSpace; if (lineWidth > MAX_LINE_WIDTH) { utilWriter.AppendIndent(linePosition, indent, reader.Depth - 1, true); lineWidth = indent; writeSpace = false; utilWriter.Flush(); sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; } else { writeSpace = true; } // Write the attribute reader.MoveToNextAttribute(); utilWriter.Flush(); int startLength = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length; if (writeSpace) { utilWriter.AppendSpace(); } utilWriter.Write(reader.Name); utilWriter.Write('='); utilWriter.AppendAttributeValue(reader); utilWriter.Flush(); lineWidth += ((StringWriter)utilWriter.Writer).GetStringBuilder().Length - startLength; } } // position reader back on element reader.MoveToElement(); // write closing tag if (reader.IsEmptyElement) { utilWriter.Write(" />"); } else { utilWriter.Write('>'); } break; case XmlNodeType.EndElement: utilWriter.Write("</"); utilWriter.Write(reader.Name); utilWriter.Write('>'); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(reader.Name); break; // Ignore <?xml and <!DOCTYPE nodes case XmlNodeType.XmlDeclaration: case XmlNodeType.DocumentType: default: break; } // put each new element on a new line newLine = true; // do not skip any more indents skipFirstIndent = false; } utilWriter.Flush(); string s = ((StringWriter)utilWriter.Writer).ToString(); return(s); }
internal static string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter writer = new StringWriter(new StringBuilder(0x40), CultureInfo.InvariantCulture); XmlUtilWriter writer2 = new XmlUtilWriter(writer, false); bool newLine = false; bool flag2 = false; int num2 = 0; while (reader.Read()) { int num; int attributeCount; int num4; bool flag3; XmlNodeType nodeType = reader.NodeType; if (flag2) { writer2.Flush(); num = num2 - ((StringWriter) writer2.Writer).GetStringBuilder().Length; } else { num = 0; } XmlNodeType type2 = nodeType; if (type2 <= XmlNodeType.CDATA) { switch (type2) { case XmlNodeType.Element: case XmlNodeType.CDATA: goto Label_0091; } goto Label_00CA; } if ((type2 != XmlNodeType.Comment) && (type2 != XmlNodeType.EndElement)) { goto Label_00CA; } Label_0091: if (!skipFirstIndent && !flag2) { writer2.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { writer2.Flush(); num2 = ((StringWriter) writer2.Writer).GetStringBuilder().Length; } } Label_00CA: flag2 = false; switch (nodeType) { case XmlNodeType.Element: writer2.Write('<'); writer2.Write(reader.Name); num += reader.Name.Length + 2; attributeCount = reader.AttributeCount; num4 = 0; goto Label_0274; case XmlNodeType.Text: writer2.AppendEscapeTextString(reader.Value); flag2 = true; goto Label_02D6; case XmlNodeType.CDATA: writer2.AppendCData(reader.Value); goto Label_02D6; case XmlNodeType.EntityReference: writer2.AppendEntityRef(reader.Name); goto Label_02D6; case XmlNodeType.ProcessingInstruction: writer2.AppendProcessingInstruction(reader.Name, reader.Value); goto Label_02D6; case XmlNodeType.Comment: writer2.AppendComment(reader.Value); goto Label_02D6; case XmlNodeType.SignificantWhitespace: writer2.Write(reader.Value); goto Label_02D6; case XmlNodeType.EndElement: writer2.Write("</"); writer2.Write(reader.Name); writer2.Write('>'); goto Label_02D6; default: goto Label_02D6; } Label_01BE: if (num > 60) { writer2.AppendIndent(linePosition, indent, reader.Depth - 1, true); num = indent; flag3 = false; writer2.Flush(); num2 = ((StringWriter) writer2.Writer).GetStringBuilder().Length; } else { flag3 = true; } reader.MoveToNextAttribute(); writer2.Flush(); int length = ((StringWriter) writer2.Writer).GetStringBuilder().Length; if (flag3) { writer2.AppendSpace(); } writer2.Write(reader.Name); writer2.Write('='); writer2.AppendAttributeValue(reader); writer2.Flush(); num += ((StringWriter) writer2.Writer).GetStringBuilder().Length - length; num4++; Label_0274: if (num4 < attributeCount) { goto Label_01BE; } reader.MoveToElement(); if (reader.IsEmptyElement) { writer2.Write(" />"); } else { writer2.Write('>'); } Label_02D6: newLine = true; skipFirstIndent = false; } writer2.Flush(); return ((StringWriter) writer2.Writer).ToString(); }
internal bool CopyXmlNode(XmlUtilWriter utilWriter) { string s = null; int fromLineNumber = -1; int fromLinePosition = -1; int lineNumber = 0; int linePosition = 0; int num5 = 0; int num6 = 0; if (utilWriter.TrackPosition) { lineNumber = this._reader.LineNumber; linePosition = this._reader.LinePosition; num5 = utilWriter.LineNumber; num6 = utilWriter.LinePosition; } XmlNodeType nodeType = this._reader.NodeType; switch (nodeType) { case XmlNodeType.Whitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.Element: s = this._reader.IsEmptyElement ? "/>" : ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(this._reader.Name); while (this._reader.MoveToNextAttribute()) { int toLineNumber = this._reader.LineNumber; int toLinePosition = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, toLineNumber, toLinePosition); int num9 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num9 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = toLineNumber; fromLinePosition = toLinePosition + num9; } break; case XmlNodeType.EndElement: s = ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(this._reader.Name); break; case XmlNodeType.Comment: utilWriter.AppendComment(this._reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(this._reader.Value); break; case XmlNodeType.XmlDeclaration: s = "?>"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + 3; utilWriter.Write("<?xml"); while (this._reader.MoveToNextAttribute()) { int num10 = this._reader.LineNumber; int num11 = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, num10, num11); int num12 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num12 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = num10; fromLinePosition = num11 + num12; } this._reader.MoveToElement(); break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(this._reader.Name, this._reader.Value); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(this._reader.Name); break; case XmlNodeType.CDATA: utilWriter.AppendCData(this._reader.Value); break; default: if (nodeType == XmlNodeType.DocumentType) { int num13 = utilWriter.Write("<!DOCTYPE"); utilWriter.AppendRequiredWhiteSpace(this._lastLineNumber, this._lastLinePosition + num13, this._reader.LineNumber, this._reader.LinePosition); utilWriter.Write(this._reader.Name); string str2 = null; if (this._reader.HasValue) { str2 = this._reader.Value; } fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; if (this._reader.MoveToFirstAttribute()) { utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, this._reader.LineNumber, this._reader.LinePosition); string name = this._reader.Name; utilWriter.Write(name); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(0); if (name == "PUBLIC") { this._reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(1); } } if ((str2 != null) && (str2.Length > 0)) { utilWriter.Write(" ["); utilWriter.Write(str2); utilWriter.Write(']'); } utilWriter.Write('>'); } break; } bool flag = this._reader.Read(); nodeType = this._reader.NodeType; if (s != null) { int positionOffset = GetPositionOffset(nodeType); int num15 = this._reader.LineNumber; int num16 = (this._reader.LinePosition - positionOffset) - s.Length; utilWriter.AppendWhiteSpace(fromLineNumber, fromLinePosition, num15, num16); utilWriter.Write(s); } if (utilWriter.TrackPosition) { this._lastLineNumber = (lineNumber - num5) + utilWriter.LineNumber; if (num5 == utilWriter.LineNumber) { this._lastLinePosition = (linePosition - num6) + utilWriter.LinePosition; return flag; } this._lastLinePosition = utilWriter.LinePosition; } return flag; }
internal static string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) { XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode); XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context); StringWriter writer = new StringWriter(new StringBuilder(0x40), CultureInfo.InvariantCulture); XmlUtilWriter writer2 = new XmlUtilWriter(writer, false); bool newLine = false; bool flag2 = false; int num2 = 0; while (reader.Read()) { int num; int attributeCount; int num4; bool flag3; XmlNodeType nodeType = reader.NodeType; if (flag2) { writer2.Flush(); num = num2 - ((StringWriter)writer2.Writer).GetStringBuilder().Length; } else { num = 0; } XmlNodeType type2 = nodeType; if (type2 <= XmlNodeType.CDATA) { switch (type2) { case XmlNodeType.Element: case XmlNodeType.CDATA: goto Label_0091; } goto Label_00CA; } if ((type2 != XmlNodeType.Comment) && (type2 != XmlNodeType.EndElement)) { goto Label_00CA; } Label_0091: if (!skipFirstIndent && !flag2) { writer2.AppendIndent(linePosition, indent, reader.Depth, newLine); if (newLine) { writer2.Flush(); num2 = ((StringWriter)writer2.Writer).GetStringBuilder().Length; } } Label_00CA: flag2 = false; switch (nodeType) { case XmlNodeType.Element: writer2.Write('<'); writer2.Write(reader.Name); num += reader.Name.Length + 2; attributeCount = reader.AttributeCount; num4 = 0; goto Label_0274; case XmlNodeType.Text: writer2.AppendEscapeTextString(reader.Value); flag2 = true; goto Label_02D6; case XmlNodeType.CDATA: writer2.AppendCData(reader.Value); goto Label_02D6; case XmlNodeType.EntityReference: writer2.AppendEntityRef(reader.Name); goto Label_02D6; case XmlNodeType.ProcessingInstruction: writer2.AppendProcessingInstruction(reader.Name, reader.Value); goto Label_02D6; case XmlNodeType.Comment: writer2.AppendComment(reader.Value); goto Label_02D6; case XmlNodeType.SignificantWhitespace: writer2.Write(reader.Value); goto Label_02D6; case XmlNodeType.EndElement: writer2.Write("</"); writer2.Write(reader.Name); writer2.Write('>'); goto Label_02D6; default: goto Label_02D6; } Label_01BE: if (num > 60) { writer2.AppendIndent(linePosition, indent, reader.Depth - 1, true); num = indent; flag3 = false; writer2.Flush(); num2 = ((StringWriter)writer2.Writer).GetStringBuilder().Length; } else { flag3 = true; } reader.MoveToNextAttribute(); writer2.Flush(); int length = ((StringWriter)writer2.Writer).GetStringBuilder().Length; if (flag3) { writer2.AppendSpace(); } writer2.Write(reader.Name); writer2.Write('='); writer2.AppendAttributeValue(reader); writer2.Flush(); num += ((StringWriter)writer2.Writer).GetStringBuilder().Length - length; num4++; Label_0274: if (num4 < attributeCount) { goto Label_01BE; } reader.MoveToElement(); if (reader.IsEmptyElement) { writer2.Write(" />"); } else { writer2.Write('>'); } Label_02D6: newLine = true; skipFirstIndent = false; } writer2.Flush(); return(((StringWriter)writer2.Writer).ToString()); }
internal bool CopyXmlNode(XmlUtilWriter utilWriter) { string s = null; int fromLineNumber = -1; int fromLinePosition = -1; int lineNumber = 0; int linePosition = 0; int num5 = 0; int num6 = 0; if (utilWriter.TrackPosition) { lineNumber = this._reader.LineNumber; linePosition = this._reader.LinePosition; num5 = utilWriter.LineNumber; num6 = utilWriter.LinePosition; } XmlNodeType nodeType = this._reader.NodeType; switch (nodeType) { case XmlNodeType.Whitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.Element: s = this._reader.IsEmptyElement ? "/>" : ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write('<'); utilWriter.Write(this._reader.Name); while (this._reader.MoveToNextAttribute()) { int toLineNumber = this._reader.LineNumber; int toLinePosition = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, toLineNumber, toLinePosition); int num9 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num9 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = toLineNumber; fromLinePosition = toLinePosition + num9; } break; case XmlNodeType.EndElement: s = ">"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; utilWriter.Write("</"); utilWriter.Write(this._reader.Name); break; case XmlNodeType.Comment: utilWriter.AppendComment(this._reader.Value); break; case XmlNodeType.Text: utilWriter.AppendEscapeTextString(this._reader.Value); break; case XmlNodeType.XmlDeclaration: s = "?>"; fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + 3; utilWriter.Write("<?xml"); while (this._reader.MoveToNextAttribute()) { int num10 = this._reader.LineNumber; int num11 = this._reader.LinePosition; utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, num10, num11); int num12 = utilWriter.Write(this._reader.Name) + utilWriter.Write('='); num12 += utilWriter.AppendAttributeValue(this._reader); fromLineNumber = num10; fromLinePosition = num11 + num12; } this._reader.MoveToElement(); break; case XmlNodeType.SignificantWhitespace: utilWriter.Write(this._reader.Value); break; case XmlNodeType.ProcessingInstruction: utilWriter.AppendProcessingInstruction(this._reader.Name, this._reader.Value); break; case XmlNodeType.EntityReference: utilWriter.AppendEntityRef(this._reader.Name); break; case XmlNodeType.CDATA: utilWriter.AppendCData(this._reader.Value); break; default: if (nodeType == XmlNodeType.DocumentType) { int num13 = utilWriter.Write("<!DOCTYPE"); utilWriter.AppendRequiredWhiteSpace(this._lastLineNumber, this._lastLinePosition + num13, this._reader.LineNumber, this._reader.LinePosition); utilWriter.Write(this._reader.Name); string str2 = null; if (this._reader.HasValue) { str2 = this._reader.Value; } fromLineNumber = this._reader.LineNumber; fromLinePosition = this._reader.LinePosition + this._reader.Name.Length; if (this._reader.MoveToFirstAttribute()) { utilWriter.AppendRequiredWhiteSpace(fromLineNumber, fromLinePosition, this._reader.LineNumber, this._reader.LinePosition); string name = this._reader.Name; utilWriter.Write(name); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(0); if (name == "PUBLIC") { this._reader.MoveToAttribute(1); utilWriter.AppendSpace(); utilWriter.AppendAttributeValue(this._reader); this._reader.MoveToAttribute(1); } } if ((str2 != null) && (str2.Length > 0)) { utilWriter.Write(" ["); utilWriter.Write(str2); utilWriter.Write(']'); } utilWriter.Write('>'); } break; } bool flag = this._reader.Read(); nodeType = this._reader.NodeType; if (s != null) { int positionOffset = GetPositionOffset(nodeType); int num15 = this._reader.LineNumber; int num16 = (this._reader.LinePosition - positionOffset) - s.Length; utilWriter.AppendWhiteSpace(fromLineNumber, fromLinePosition, num15, num16); utilWriter.Write(s); } if (utilWriter.TrackPosition) { this._lastLineNumber = (lineNumber - num5) + utilWriter.LineNumber; if (num5 == utilWriter.LineNumber) { this._lastLinePosition = (linePosition - num6) + utilWriter.LinePosition; return(flag); } this._lastLinePosition = utilWriter.LinePosition; } return(flag); }