public void Process( XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { if (elementProcessContext.Current.IsPreservingSpace) { output.Append("</").Append(xmlReader.Name).Append(">"); } else if (elementProcessContext.Current.IsSignificantWhiteSpace && !output.IsNewLine()) { output.Append("</").Append(xmlReader.Name).Append(">"); } else if ((elementProcessContext.Current.ContentType == ContentTypeEnum.None) && this.options.RemoveEndingTagOfEmptyElement) { // Shrink the current element, if it has no content. // E.g., <Element> </Element> => <Element /> output = output.TrimEnd(' ', '\t', '\r', '\n'); int bracketIndex = output.LastIndexOf('>'); output.Insert(bracketIndex, '/'); if ((output[bracketIndex - 1] != '\t') && (output[bracketIndex - 1] != ' ') && this.options.SpaceBeforeClosingSlash) { output.Insert(bracketIndex, ' '); } } else if ((elementProcessContext.Current.ContentType == ContentTypeEnum.SingleLineTextOnly) && !elementProcessContext.Current.IsMultlineStartTag) { int bracketIndex = output.LastIndexOf('>'); string text = output.Substring((bracketIndex + 1), (output.Length - bracketIndex - 1)).Trim(); output.Length = (bracketIndex + 1); output.Append(text).Append("</").Append(xmlReader.Name).Append(">"); } else { string currentIndentString = this.indentService.GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("</").Append(xmlReader.Name).Append(">"); } elementProcessContext.Pop(); }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { if (elementProcessContext.Current.IsPreservingSpace) { output.Append("</").Append(xmlReader.Name).Append(">"); } else if (elementProcessContext.Current.IsSignificantWhiteSpace && !output.IsNewLine()) { output.Append("</").Append(xmlReader.Name).Append(">"); } // Shrink the current element, if it has no content. // E.g., <Element> </Element> => <Element /> else if (elementProcessContext.Current.ContentType == ContentTypeEnum.NONE && _options.RemoveEndingTagOfEmptyElement) { #region shrink element with no content output = output.TrimEnd(' ', '\t', '\r', '\n'); int bracketIndex = output.LastIndexOf('>'); output.Insert(bracketIndex, '/'); if (output[bracketIndex - 1] != '\t' && output[bracketIndex - 1] != ' ' && _options.SpaceBeforeClosingSlash) { output.Insert(bracketIndex, ' '); } #endregion shrink element with no content } else if (elementProcessContext.Current.ContentType == ContentTypeEnum.SINGLE_LINE_TEXT_ONLY && elementProcessContext.Current.IsMultlineStartTag == false) { int bracketIndex = output.LastIndexOf('>'); string text = output.Substring(bracketIndex + 1, output.Length - bracketIndex - 1).Trim(); output.Length = bracketIndex + 1; output.Append(text).Append("</").Append(xmlReader.Name).Append(">"); } else { string currentIndentString = _indentService.GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("</").Append(xmlReader.Name).Append(">"); } elementProcessContext.Pop(); }
private void ProcessEndElement(XmlReader xmlReader, StringBuilder output) { if (_elementProcessStatusStack.Peek().IsPreservingSpace) { output.Append("</").Append(xmlReader.Name).Append(">"); } else if (_elementProcessStatusStack.Peek().IsSignificantWhiteSpace&& !output.IsNewLine()) { output.Append("</").Append(xmlReader.Name).Append(">"); } // Shrink the current element, if it has no content. // E.g., <Element> </Element> => <Element /> else if (ContentTypeEnum.NONE == _elementProcessStatusStack.Peek().ContentType && Options.RemoveEndingTagOfEmptyElement) { #region shrink element with no content output = output.TrimEnd(' ', '\t', '\r', '\n'); int bracketIndex = output.LastIndexOf('>'); output.Insert(bracketIndex, '/'); if (output[bracketIndex - 1] != '\t' && output[bracketIndex - 1] != ' ' && Options.SpaceBeforeClosingSlash) { output.Insert(bracketIndex, ' '); } #endregion shrink element with no content } else if (ContentTypeEnum.SINGLE_LINE_TEXT_ONLY == _elementProcessStatusStack.Peek().ContentType && false == _elementProcessStatusStack.Peek().IsMultlineStartTag) { int bracketIndex = output.LastIndexOf('>'); string text = output.Substring(bracketIndex + 1, output.Length - bracketIndex - 1).Trim(); output.Length = bracketIndex + 1; output.Append(text).Append("</").Append(xmlReader.Name).Append(">"); } else { string currentIndentString = GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("</").Append(xmlReader.Name).Append(">"); } }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { // If there is linefeed(s) between element and CDATA then treat CDATA as element and // indent accordingly, otherwise treat as single line text. if (output.IsNewLine()) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypes.MultiLineTextOnly); if (!elementProcessContext.Current.IsPreservingSpace) { string currentIndentString = this.indentService.GetIndentString(xmlReader.Depth); output.Append(currentIndentString); } } else { elementProcessContext.UpdateParentElementProcessStatus(ContentTypes.SingleLineTextOnly); } // All newlines are returned by XmlReader as '\n' due to requirements in the XML Specification. // http://www.w3.org/TR/2008/REC-xml-20081126/#sec-line-ends // Change them back into the environment newline characters. output.Append("<![CDATA[") .Append(xmlReader.Value.Replace("\n", Environment.NewLine)) .Append("]]>"); }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypeEnum.Mixed); string currentIndentString = this.indentService.GetIndentString(xmlReader.Depth); string content = xmlReader.Value; if ((output.Length > 0) && !output.IsNewLine()) { output.Append(Environment.NewLine); } if (content.Contains("<") && content.Contains(">")) { output.Append(currentIndentString); output.Append("<!--"); if (content.Contains("\n")) { output.Append(String.Join(Environment.NewLine, content.GetLines().Select(_ => _.TrimEnd(' ')))); if (content.TrimEnd(' ').EndsWith("\n")) { output.Append(currentIndentString); } } else { output.Append(content); } output.Append("-->"); } else if (content.Contains("#region") || content.Contains("#endregion")) { output.Append(currentIndentString).Append("<!--").Append(content.Trim()).Append("-->"); } else if (content.Contains("\n")) { output.Append(currentIndentString).Append("<!--"); var contentIndentString = this.indentService.GetIndentString(xmlReader.Depth + 1); foreach (var line in content.Trim().GetLines()) { output.Append(Environment.NewLine).Append(contentIndentString).Append(line.Trim()); } output.Append(Environment.NewLine).Append(currentIndentString).Append("-->"); } else { output .Append(currentIndentString) .Append("<!--") .Append(' ', this.options.CommentSpaces) .Append(content.Trim()) .Append(' ', this.options.CommentSpaces) .Append("-->"); } }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { // If there is linefeed(s) between element and CDATA then treat CDATA as element and // indent accordingly, otherwise treat as single line text. if (output.IsNewLine()) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypeEnum.MultiLineTextOnly); if (!elementProcessContext.Current.IsPreservingSpace) { string currentIndentString = this.indentService.GetIndentString(xmlReader.Depth); output.Append(currentIndentString); } } else { elementProcessContext.UpdateParentElementProcessStatus(ContentTypeEnum.SingleLineTextOnly); } // All newlines are returned by XmlReader as '\n' due to requirements in the XML Specification. // http://www.w3.org/TR/2008/REC-xml-20081126/#sec-line-ends // Change them back into the environment newline characters. output.Append("<![CDATA[") .Append(xmlReader.Value.Replace("\n", Environment.NewLine)) .Append("]]>"); }
private void ProcessComment(XmlReader xmlReader, StringBuilder output) { string currentIndentString = GetIndentString(xmlReader.Depth); string content = xmlReader.Value; if (!output.IsNewLine()) { output.Append(Environment.NewLine); } if (content.Contains("<") && content.Contains(">")) { output.Append(currentIndentString); output.Append("<!--"); if (content.Contains("\n")) { output.Append(string.Join(Environment.NewLine, content.GetLines().Select(x => x.TrimEnd(' ')))); if (content.TrimEnd(' ').EndsWith("\n")) { output.Append(currentIndentString); } } else { output.Append(content); } output.Append("-->"); } else if (content.Contains("\n")) { output .Append(currentIndentString) .Append("<!--"); var contentIndentString = GetIndentString(xmlReader.Depth + 1); foreach (var line in content.Trim().GetLines()) { output .Append(Environment.NewLine) .Append(contentIndentString) .Append(line.Trim()); } output .Append(Environment.NewLine) .Append(currentIndentString) .Append("-->"); } else { output .Append(currentIndentString) .Append("<!-- ") .Append(content.Trim()) .Append(" -->"); } }
private void ProcessInstruction(XmlReader xmlReader, StringBuilder output) { string currentIndentString = this.GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("<?Mapping ").Append(xmlReader.Value).Append(" ?>"); }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypeEnum.MIXED); string currentIndentString = _indentService.GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("<?Mapping ").Append(xmlReader.Value).Append(" ?>"); }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypeEnum.Mixed); string currentIndentString = this.indentService.GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("<?Mapping ").Append(xmlReader.Value).Append(" ?>"); }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypes.Mixed); string currentIndentString = this.indentService.GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append($"{currentIndentString}<?{xmlReader.Name} {xmlReader.Value}?>"); }
private void ProcessCDATA(XmlReader xmlReader, StringBuilder output) { // If there is linefeed(s) between element and CDATA then treat CDATA as element and indent accordingly, otherwise treat as single line text if (output.IsNewLine()) { UpdateParentElementProcessStatus(ContentTypeEnum.MULTI_LINE_TEXT_ONLY); if (!_elementProcessStatusStack.Peek().IsPreservingSpace) { string currentIndentString = GetIndentString(xmlReader.Depth); output.Append(currentIndentString); } } else { UpdateParentElementProcessStatus(ContentTypeEnum.SINGLE_LINE_TEXT_ONLY); } output .Append("<![CDATA[") // All newlines are returned by XmlReader as \n due to requirements in the XML Specification (http://www.w3.org/TR/2008/REC-xml-20081126/#sec-line-ends) // Change them back into the environment newline characters. .Append(xmlReader.Value.Replace("\n", Environment.NewLine)) .Append("]]>"); }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypeEnum.Mixed); var elementName = xmlReader.Name; elementProcessContext.Push( new ElementProcessStatus { Parent = elementProcessContext.Current, Name = elementName, ContentType = ContentTypeEnum.None, IsMultlineStartTag = false, IsPreservingSpace = elementProcessContext.Current.IsPreservingSpace }); var currentIndentString = this.indentService.GetIndentString(xmlReader.Depth); var attributeIndetationString = this.GetAttributeIndetationString(xmlReader); // Calculate how element should be indented if (!elementProcessContext.Current.IsPreservingSpace) { // "Run" get special treatment to try to preserve spacing. Use xml:space='preserve' to make sure! if (elementName.Equals("Run")) { elementProcessContext.Current.Parent.IsSignificantWhiteSpace = true; if ((output.Length == 0) || output.IsNewLine()) { output.Append(currentIndentString); } } else { elementProcessContext.Current.Parent.IsSignificantWhiteSpace = false; if ((output.Length == 0) || output.IsNewLine()) { output.Append(currentIndentString); } else { output.Append(Environment.NewLine).Append(currentIndentString); } } } // Output the element itself. output.Append('<').Append(elementName); bool isEmptyElement = xmlReader.IsEmptyElement; if (xmlReader.HasAttributes) { bool isNoLineBreakElement = this.IsNoLineBreakElement(elementName); this.ProcessAttributes( xmlReader, output, elementProcessContext, isNoLineBreakElement, attributeIndetationString); } // Determine if to put ending bracket on new line. bool putEndingBracketOnNewLine = (this.options.PutEndingBracketOnNewLine && elementProcessContext.Current.IsMultlineStartTag); if (putEndingBracketOnNewLine) { // Indent ending bracket just like an attribute. output.Append(Environment.NewLine).Append(attributeIndetationString); } if (isEmptyElement) { if (!putEndingBracketOnNewLine && this.options.SpaceBeforeClosingSlash) { output.Append(' '); } output.Append("/>"); // Self closing element. Remember to pop element context. elementProcessContext.Pop(); } else { output.Append(">"); } }
private void ProcessElement(XmlReader xmlReader, StringBuilder output) { string currentIndentString = GetIndentString(xmlReader.Depth); string elementName = xmlReader.Name; if ("Run".Equals(elementName)) { if (output.IsNewLine()) { // Shall not add extra whitespaces (including linefeeds) before <Run/>, // because it will affect the rendering of <TextBlock><Run/><Run/></TextBlock> output .Append(currentIndentString) .Append('<') .Append(xmlReader.Name); } else { output.Append('<'); output.Append(xmlReader.Name); } } else if (output.Length == 0 || output.IsNewLine()) { output .Append(currentIndentString) .Append('<') .Append(xmlReader.Name); } else { output .Append(Environment.NewLine) .Append(currentIndentString) .Append('<') .Append(xmlReader.Name); } bool isEmptyElement = xmlReader.IsEmptyElement; bool hasPutEndingBracketOnNewLine = false; var list = new List <AttributeInfo>(xmlReader.AttributeCount); if (xmlReader.HasAttributes) { while (xmlReader.MoveToNextAttribute()) { string attributeName = xmlReader.Name; string attributeValue = xmlReader.Value; AttributeOrderRule orderRule = OrderRules.GetRuleFor(attributeName); list.Add(new AttributeInfo(attributeName, attributeValue, orderRule)); } if (Options.OrderAttributesByName) { list.Sort(); } currentIndentString = GetIndentString(xmlReader.Depth); var noLineBreakInAttributes = (list.Count <= Options.AttributesTolerance) || IsNoLineBreakElement(elementName); // Root element? if (_elementProcessStatusStack.Count == 2) { switch (Options.RootElementLineBreakRule) { case LineBreakRule.Default: break; case LineBreakRule.Always: noLineBreakInAttributes = false; break; case LineBreakRule.Never: noLineBreakInAttributes = true; break; default: throw new ArgumentOutOfRangeException(); } } // No need to break attributes if (noLineBreakInAttributes) { foreach (var attrInfo in list) { output .Append(' ') .Append(attrInfo.ToSingleLineString()); } _elementProcessStatusStack.Peek().IsMultlineStartTag = false; } // Need to break attributes else { IList <String> attributeLines = new List <String>(); var currentLineBuffer = new StringBuilder(); int attributeCountInCurrentLineBuffer = 0; AttributeInfo lastAttributeInfo = null; foreach (AttributeInfo attrInfo in list) { // Attributes with markup extension, always put on new line if (attrInfo.IsMarkupExtension && Options.FormatMarkupExtension) { string baseIndetationString; if (!Options.KeepFirstAttributeOnSameLine) { baseIndetationString = GetIndentString(xmlReader.Depth); } else { baseIndetationString = GetIndentString(xmlReader.Depth - 1) + string.Empty.PadLeft(elementName.Length + 2, ' '); } string pendingAppend; //Keep binding and / or x:bind on same line? if ((attrInfo.Value.ToLower().Contains("x:bind ") && Options.KeepxBindOnSameLine) || Options.KeepBindingsOnSameLine) { pendingAppend = " " + attrInfo.ToSingleLineString(); } else { pendingAppend = attrInfo.ToMultiLineString(baseIndetationString); } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } attributeLines.Add(pendingAppend); } else { string pendingAppend = attrInfo.ToSingleLineString(); bool isAttributeCharLengthExceeded = (attributeCountInCurrentLineBuffer > 0 && Options.MaxAttributeCharatersPerLine > 0 && currentLineBuffer.Length + pendingAppend.Length > Options.MaxAttributeCharatersPerLine); bool isAttributeCountExceeded = (Options.MaxAttributesPerLine > 0 && attributeCountInCurrentLineBuffer + 1 > Options.MaxAttributesPerLine); bool isAttributeRuleGroupChanged = Options.PutAttributeOrderRuleGroupsOnSeparateLines && lastAttributeInfo != null && lastAttributeInfo.OrderRule.AttributeTokenType != attrInfo.OrderRule.AttributeTokenType; if (isAttributeCharLengthExceeded || isAttributeCountExceeded || isAttributeRuleGroupChanged) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } currentLineBuffer.AppendFormat("{0} ", pendingAppend); attributeCountInCurrentLineBuffer++; } lastAttributeInfo = attrInfo; } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); } for (int i = 0; i < attributeLines.Count; i++) { if (0 == i && Options.KeepFirstAttributeOnSameLine) { output .Append(' ') .Append(attributeLines[i].Trim()); // Align subsequent attributes with first attribute currentIndentString = GetIndentString(xmlReader.Depth - 1) + String.Empty.PadLeft(elementName.Length + 2, ' '); continue; } output .Append(Environment.NewLine) .Append(currentIndentString) .Append(attributeLines[i].Trim()); } _elementProcessStatusStack.Peek().IsMultlineStartTag = true; } // Determine if to put ending bracket on new line if (Options.PutEndingBracketOnNewLine && _elementProcessStatusStack.Peek().IsMultlineStartTag) { output .Append(Environment.NewLine) .Append(currentIndentString); hasPutEndingBracketOnNewLine = true; } } if (isEmptyElement) { if (hasPutEndingBracketOnNewLine == false && Options.SpaceBeforeClosingSlash) { output.Append(' '); } output.Append("/>"); _elementProcessStatusStack.Peek().IsSelfClosingElement = true; } else { output.Append(">"); } }
public void Process(XmlReader xmlReader, StringBuilder output, ElementProcessContext elementProcessContext) { elementProcessContext.UpdateParentElementProcessStatus(ContentTypeEnum.MIXED); var elementName = xmlReader.Name; elementProcessContext.Push( new ElementProcessStatus { Parent = elementProcessContext.Current, Name = elementName, ContentType = ContentTypeEnum.NONE, IsMultlineStartTag = false, IsPreservingSpace = elementProcessContext.Current.IsPreservingSpace } ); var currentIndentString = _indentService.GetIndentString(xmlReader.Depth); var attributeIndetationString = GetAttributeIndetationString(xmlReader); // Calculate how element should be indented if (!elementProcessContext.Current.IsPreservingSpace) { // "Run" get special treatment to try to preserve spacing. Use xml:space='preserve' to make sure! if (elementName.Equals("Run")) { elementProcessContext.Current.Parent.IsSignificantWhiteSpace = true; if (output.Length == 0 || output.IsNewLine()) { output.Append(currentIndentString); } } else { elementProcessContext.Current.Parent.IsSignificantWhiteSpace = false; if (output.Length == 0 || output.IsNewLine()) { output.Append(currentIndentString); } else { output .Append(Environment.NewLine) .Append(currentIndentString); } } } // Output the element itself output .Append('<') .Append(elementName); bool isEmptyElement = xmlReader.IsEmptyElement; if (xmlReader.HasAttributes) { bool isNoLineBreakElement = IsNoLineBreakElement(elementName); ProcessAttributes(xmlReader, output, elementProcessContext, isNoLineBreakElement, attributeIndetationString); } // Determine if to put ending bracket on new line bool putEndingBracketOnNewLine = (_options.PutEndingBracketOnNewLine && elementProcessContext.Current.IsMultlineStartTag); if(putEndingBracketOnNewLine) { // Indent ending bracket just like an attribute output .Append(Environment.NewLine) .Append(attributeIndetationString); } if (isEmptyElement) { if (putEndingBracketOnNewLine == false && _options.SpaceBeforeClosingSlash) { output.Append(' '); } output.Append("/>"); // Self closing element. Remember to pop element context. elementProcessContext.Pop(); } else { output.Append(">"); } }
private void ProcessEndElement(XmlReader xmlReader, StringBuilder output) { if (this.ElementProcessStatusStack.Peek().IsPreservingSpace) { output.Append("</").Append(xmlReader.Name).Append(">"); } else if (this.ElementProcessStatusStack.Peek().IsSignificantWhiteSpace && !output.IsNewLine()) { output.Append("</").Append(xmlReader.Name).Append(">"); } // Shrink the current element, if it has no content. // E.g., <Element> </Element> => <Element /> else if ((ContentTypeEnum.None == this.ElementProcessStatusStack.Peek().ContentType) && Options.RemoveEndingTagOfEmptyElement) { #region shrink element with no content output = output.TrimEnd(' ', '\t', '\r', '\n'); int bracketIndex = output.LastIndexOf('>'); output.Insert(bracketIndex, '/'); if ((output[bracketIndex - 1] != '\t') && (output[bracketIndex - 1] != ' ') && Options.SpaceBeforeClosingSlash) { output.Insert(bracketIndex, ' '); } #endregion shrink element with no content } else if ((ContentTypeEnum.SingleLineTextOnly == this.ElementProcessStatusStack.Peek().ContentType) && !this.ElementProcessStatusStack.Peek().IsMultlineStartTag) { int bracketIndex = output.LastIndexOf('>'); string text = output.Substring(bracketIndex + 1, output.Length - bracketIndex - 1).Trim(); output.Length = bracketIndex + 1; output.Append(text).Append("</").Append(xmlReader.Name).Append(">"); } else { string currentIndentString = this.GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("</").Append(xmlReader.Name).Append(">"); } }
private void ProcessElement(XmlReader xmlReader, StringBuilder output) { string currentIndentString = GetIndentString(xmlReader.Depth); string elementName = xmlReader.Name; // Calculate how element should be indented if (!this.ElementProcessStatusStack.Peek().IsPreservingSpace) { // "Run" get special treatment to try to preserve spacing. Use xml:space='preserve' to make sure! if (elementName.Equals("Run")) { this.ElementProcessStatusStack.Peek().Parent.IsSignificantWhiteSpace = true; if ((output.Length == 0) || output.IsNewLine()) { output.Append(currentIndentString); } } else { this.ElementProcessStatusStack.Peek().Parent.IsSignificantWhiteSpace = false; if ((output.Length == 0) || output.IsNewLine()) { output.Append(currentIndentString); } else { output.Append(Environment.NewLine).Append(currentIndentString); } } } // Output the element itself output.Append('<').Append(xmlReader.Name); bool isEmptyElement = xmlReader.IsEmptyElement; bool hasPutEndingBracketOnNewLine = false; var list = new List<AttributeInfo>(xmlReader.AttributeCount); if (xmlReader.HasAttributes) { while (xmlReader.MoveToNextAttribute()) { string attributeName = xmlReader.Name; string attributeValue = xmlReader.Value; AttributeOrderRule orderRule = OrderRules.GetRuleFor(attributeName); list.Add(new AttributeInfo(attributeName, attributeValue, orderRule)); // Check for xml:space as defined in http://www.w3.org/TR/2008/REC-xml-20081126/#sec-white-space if (xmlReader.IsXmlSpaceAttribute()) { this.ElementProcessStatusStack.Peek().IsPreservingSpace = (xmlReader.Value == "preserve"); } } if (this.Options.EnableAttributeReordering) { list.Sort(AttributeInfoComparison); } currentIndentString = this.GetIndentString(xmlReader.Depth); var noLineBreakInAttributes = (list.Count <= this.Options.AttributesTolerance) || this.IsNoLineBreakElement(elementName); var forceLineBreakInAttributes = false; // Root element? if (this.ElementProcessStatusStack.Count == 2) { switch (this.Options.RootElementLineBreakRule) { case LineBreakRule.Default: break; case LineBreakRule.Always: noLineBreakInAttributes = false; forceLineBreakInAttributes = true; break; case LineBreakRule.Never: noLineBreakInAttributes = true; break; default: throw new ArgumentOutOfRangeException(); } } // No need to break attributes if (noLineBreakInAttributes) { foreach (var attrInfo in list) { output.Append(' ').Append(attrInfo.ToSingleLineString()); } this.ElementProcessStatusStack.Peek().IsMultlineStartTag = false; } // Need to break attributes else { IList<String> attributeLines = new List<String>(); var currentLineBuffer = new StringBuilder(); int attributeCountInCurrentLineBuffer = 0; AttributeInfo lastAttributeInfo = null; foreach (AttributeInfo attrInfo in list) { // Attributes with markup extension, always put on new line if (attrInfo.IsMarkupExtension && this.Options.FormatMarkupExtension) { string baseIndetationString; if (!this.Options.KeepFirstAttributeOnSameLine) { baseIndetationString = this.GetIndentString(xmlReader.Depth); } else { baseIndetationString = this.GetIndentString(xmlReader.Depth - 1) + String.Empty.PadLeft(elementName.Length + 2, ' '); } string pendingAppend; if (this.NoNewLineMarkupExtensionsList.Contains(attrInfo.MarkupExtension)) { pendingAppend = $" {attrInfo.ToSingleLineString()}"; } else { pendingAppend = attrInfo.ToMultiLineString(baseIndetationString); } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } attributeLines.Add(pendingAppend); } else { string pendingAppend = attrInfo.ToSingleLineString(); bool isAttributeCharLengthExceeded = (attributeCountInCurrentLineBuffer > 0) && (Options.MaxAttributeCharatersPerLine > 0) && ((currentLineBuffer.Length + pendingAppend.Length) > Options.MaxAttributeCharatersPerLine); bool isAttributeCountExceeded = (Options.MaxAttributesPerLine > 0) && ((attributeCountInCurrentLineBuffer + 1) > Options.MaxAttributesPerLine); bool isAttributeRuleGroupChanged = Options.SeparateByGroups && (lastAttributeInfo != null) && (lastAttributeInfo.OrderRule.Group != attrInfo.OrderRule.Group); if ((currentLineBuffer.Length > 0) && (forceLineBreakInAttributes || isAttributeCharLengthExceeded || isAttributeCountExceeded || isAttributeRuleGroupChanged)) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } currentLineBuffer.AppendFormat("{0} ", pendingAppend); attributeCountInCurrentLineBuffer++; } lastAttributeInfo = attrInfo; } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); } for (int i = 0; i < attributeLines.Count; i++) { if ((i == 0) && this.Options.KeepFirstAttributeOnSameLine) { output.Append(' ').Append(attributeLines[i].Trim()); // Align subsequent attributes with first attribute currentIndentString = GetIndentString(xmlReader.Depth - 1) + String.Empty.PadLeft(elementName.Length + 2, ' '); continue; } output.Append(Environment.NewLine).Append(currentIndentString).Append(attributeLines[i].Trim()); } this.ElementProcessStatusStack.Peek().IsMultlineStartTag = true; } // Determine if to put ending bracket on new line if (this.Options.PutEndingBracketOnNewLine && this.ElementProcessStatusStack.Peek().IsMultlineStartTag) { output.Append(Environment.NewLine).Append(currentIndentString); hasPutEndingBracketOnNewLine = true; } } if (isEmptyElement) { if (!hasPutEndingBracketOnNewLine && this.Options.SpaceBeforeClosingSlash) { output.Append(' '); } output.Append("/>"); this.ElementProcessStatusStack.Peek().IsSelfClosingElement = true; } else { output.Append(">"); } }
private void ProcessComment(XmlReader xmlReader, StringBuilder output) { string currentIndentString = GetIndentString(xmlReader.Depth); string content = xmlReader.Value; if (output.Length > 0 && !output.IsNewLine()) { output.Append(Environment.NewLine); } if (content.Contains("<") && content.Contains(">")) { output.Append(currentIndentString); output.Append("<!--"); if (content.Contains("\n")) { output.Append(String.Join(Environment.NewLine, content.GetLines().Select(_ => _.TrimEnd(' ')))); if (content.TrimEnd(' ').EndsWith("\n")) { output.Append(currentIndentString); } } else { output.Append(content); } output.Append("-->"); } else if (content.Contains("#region") || content.Contains("#endregion")) { output.Append(currentIndentString).Append("<!--").Append(content.Trim()).Append("-->"); } else if (content.Contains("\n")) { output.Append(currentIndentString).Append("<!--"); var contentIndentString = this.GetIndentString(xmlReader.Depth + 1); foreach (var line in content.Trim().GetLines()) { output.Append(Environment.NewLine).Append(contentIndentString).Append(line.Trim()); } output.Append(Environment.NewLine).Append(currentIndentString).Append("-->"); } else { output.Append(currentIndentString) .Append("<!--") .Append(' ', Options.CommentPadding) .Append(content.Trim()) .Append(' ', Options.CommentPadding) .Append("-->"); } }
private void ProcessEndElement(XmlReader xmlReader, StringBuilder output) { // Shrink the current element, if it has no content. // E.g., <Element> </Element> => <Element /> if (ContentTypeEnum.NONE == _elementProcessStatusStack.Peek().ContentType && Options.RemoveEndingTagOfEmptyElement) { #region shrink element with no content output = output.TrimEnd(' ', '\t', '\r', '\n'); int bracketIndex = output.LastIndexOf('>'); output.Insert(bracketIndex, '/'); if (output[bracketIndex - 1] != '\t' && output[bracketIndex - 1] != ' ' && Options.SpaceBeforeClosingSlash) { output.Insert(bracketIndex, ' '); } #endregion shrink element with no content } else if (ContentTypeEnum.SINGLE_LINE_TEXT_ONLY == _elementProcessStatusStack.Peek().ContentType && false == _elementProcessStatusStack.Peek().IsMultlineStartTag) { int bracketIndex = output.LastIndexOf('>'); string text = output.Substring(bracketIndex + 1, output.Length - bracketIndex - 1).Trim(); output.Length = bracketIndex + 1; output.Append(text).Append("</").Append(xmlReader.Name).Append(">"); } else { string currentIndentString = GetIndentString(xmlReader.Depth); if (!output.IsNewLine()) { output.Append(Environment.NewLine); } output.Append(currentIndentString).Append("</").Append(xmlReader.Name).Append(">"); } }
private void ProcessElement(XmlReader xmlReader, StringBuilder output) { string currentIndentString = GetIndentString(xmlReader.Depth); string elementName = xmlReader.Name; if ("Run".Equals(elementName)) { if (output.IsNewLine()) { // Shall not add extra whitespaces (including linefeeds) before <Run/>, // because it will affect the rendering of <TextBlock><Run/><Run/></TextBlock> output .Append(currentIndentString) .Append('<') .Append(xmlReader.Name); } else { output.Append('<'); output.Append(xmlReader.Name); } } else if (output.Length == 0 || output.IsNewLine()) { output .Append(currentIndentString) .Append('<') .Append(xmlReader.Name); } else { output .Append(Environment.NewLine) .Append(currentIndentString) .Append('<') .Append(xmlReader.Name); } bool isEmptyElement = xmlReader.IsEmptyElement; bool hasPutEndingBracketOnNewLine = false; var list = new List<AttributeInfo>(xmlReader.AttributeCount); if (xmlReader.HasAttributes) { while (xmlReader.MoveToNextAttribute()) { string attributeName = xmlReader.Name; string attributeValue = xmlReader.Value; AttributeOrderRule orderRule = OrderRules.GetRuleFor(attributeName); list.Add(new AttributeInfo(attributeName, attributeValue, orderRule)); } if (Options.OrderAttributesByName) list.Sort(); currentIndentString = GetIndentString(xmlReader.Depth); var noLineBreakInAttributes = (list.Count <= Options.AttributesTolerance) || IsNoLineBreakElement(elementName); // Root element? if (_elementProcessStatusStack.Count == 2) { switch (Options.RootElementLineBreakRule) { case LineBreakRule.Default: break; case LineBreakRule.Always: noLineBreakInAttributes = false; break; case LineBreakRule.Never: noLineBreakInAttributes = true; break; default: throw new ArgumentOutOfRangeException(); } } // No need to break attributes if (noLineBreakInAttributes) { foreach (var attrInfo in list) { output .Append(' ') .Append(attrInfo.ToSingleLineString()); } _elementProcessStatusStack.Peek().IsMultlineStartTag = false; } // Need to break attributes else { IList<String> attributeLines = new List<String>(); var currentLineBuffer = new StringBuilder(); int attributeCountInCurrentLineBuffer = 0; AttributeInfo lastAttributeInfo = null; foreach (AttributeInfo attrInfo in list) { // Attributes with markup extension, always put on new line if (attrInfo.IsMarkupExtension && Options.FormatMarkupExtension) { string baseIndetationString; if (!Options.KeepFirstAttributeOnSameLine) { baseIndetationString = GetIndentString(xmlReader.Depth); } else { baseIndetationString = GetIndentString(xmlReader.Depth - 1) + string.Empty.PadLeft(elementName.Length + 2, ' '); } string pendingAppend; //Keep binding and / or x:bind on same line? if ((attrInfo.Value.ToLower().Contains("x:bind ") && Options.KeepxBindOnSameLine) || Options.KeepBindingsOnSameLine) { pendingAppend = " " + attrInfo.ToSingleLineString(); } else { pendingAppend = attrInfo.ToMultiLineString(baseIndetationString); } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } attributeLines.Add(pendingAppend); } else { string pendingAppend = attrInfo.ToSingleLineString(); bool isAttributeCharLengthExceeded = (attributeCountInCurrentLineBuffer > 0 && Options.MaxAttributeCharatersPerLine > 0 && currentLineBuffer.Length + pendingAppend.Length > Options.MaxAttributeCharatersPerLine); bool isAttributeCountExceeded = (Options.MaxAttributesPerLine > 0 && attributeCountInCurrentLineBuffer + 1 > Options.MaxAttributesPerLine); bool isAttributeRuleGroupChanged = Options.PutAttributeOrderRuleGroupsOnSeparateLines && lastAttributeInfo != null && lastAttributeInfo.OrderRule.AttributeTokenType != attrInfo.OrderRule.AttributeTokenType; if (isAttributeCharLengthExceeded || isAttributeCountExceeded || isAttributeRuleGroupChanged) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } currentLineBuffer.AppendFormat("{0} ", pendingAppend); attributeCountInCurrentLineBuffer++; } lastAttributeInfo = attrInfo; } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); } for (int i = 0; i < attributeLines.Count; i++) { if (0 == i && Options.KeepFirstAttributeOnSameLine) { output .Append(' ') .Append(attributeLines[i].Trim()); // Align subsequent attributes with first attribute currentIndentString = GetIndentString(xmlReader.Depth - 1) + String.Empty.PadLeft(elementName.Length + 2, ' '); continue; } output .Append(Environment.NewLine) .Append(currentIndentString) .Append(attributeLines[i].Trim()); } _elementProcessStatusStack.Peek().IsMultlineStartTag = true; } // Determine if to put ending bracket on new line if (Options.PutEndingBracketOnNewLine && _elementProcessStatusStack.Peek().IsMultlineStartTag) { output .Append(Environment.NewLine) .Append(currentIndentString); hasPutEndingBracketOnNewLine = true; } } if (isEmptyElement) { if (hasPutEndingBracketOnNewLine == false && Options.SpaceBeforeClosingSlash) { output.Append(' '); } output.Append("/>"); _elementProcessStatusStack.Peek().IsSelfClosingElement = true; } else { output.Append(">"); } }
private void ProcessElement(XmlReader xmlReader, StringBuilder output) { string currentIndentString = GetIndentString(xmlReader.Depth); string elementName = xmlReader.Name; // Calculate how element should be indented if (!_elementProcessStatusStack.Peek().IsPreservingSpace) { // "Run" get special treatment to try to preserve spacing. Use xml:space='preserve' to make sure! if (elementName.Equals("Run")) { _elementProcessStatusStack.Peek().Parent.IsSignificantWhiteSpace = true; if (output.Length == 0 || output.IsNewLine()) { output.Append(currentIndentString); } } else { _elementProcessStatusStack.Peek().Parent.IsSignificantWhiteSpace = false; if (output.Length == 0 || output.IsNewLine()) { output.Append(currentIndentString); } else { output .Append(Environment.NewLine) .Append(currentIndentString); } } } // Output the element itself output .Append('<') .Append(xmlReader.Name); bool isEmptyElement = xmlReader.IsEmptyElement; bool hasPutEndingBracketOnNewLine = false; var list = new List <AttributeInfo>(xmlReader.AttributeCount); if (xmlReader.HasAttributes) { while (xmlReader.MoveToNextAttribute()) { string attributeName = xmlReader.Name; string attributeValue = xmlReader.Value; AttributeOrderRule orderRule = OrderRules.GetRuleFor(attributeName); list.Add(new AttributeInfo(attributeName, attributeValue, orderRule)); // Check for xml:space as defined in http://www.w3.org/TR/2008/REC-xml-20081126/#sec-white-space if (xmlReader.IsXmlSpaceAttribute()) { _elementProcessStatusStack.Peek().IsPreservingSpace = (xmlReader.Value == "preserve"); } } if (Options.EnableAttributeReordering) { list.Sort(AttributeInfoComparison); } currentIndentString = GetIndentString(xmlReader.Depth); var noLineBreakInAttributes = (list.Count <= Options.AttributesTolerance) || IsNoLineBreakElement(elementName); var forceLineBreakInAttributes = false; // Root element? if (_elementProcessStatusStack.Count == 2) { switch (Options.RootElementLineBreakRule) { case LineBreakRule.Default: break; case LineBreakRule.Always: noLineBreakInAttributes = false; forceLineBreakInAttributes = true; break; case LineBreakRule.Never: noLineBreakInAttributes = true; break; default: throw new ArgumentOutOfRangeException(); } } // No need to break attributes if (noLineBreakInAttributes) { foreach (var attrInfo in list) { output .Append(' ') .Append(attrInfo.ToSingleLineString()); } _elementProcessStatusStack.Peek().IsMultlineStartTag = false; } // Need to break attributes else { IList <String> attributeLines = new List <String>(); var currentLineBuffer = new StringBuilder(); int attributeCountInCurrentLineBuffer = 0; AttributeInfo lastAttributeInfo = null; foreach (AttributeInfo attrInfo in list) { // Attributes with markup extension, always put on new line if (attrInfo.IsMarkupExtension && Options.FormatMarkupExtension) { string baseIndetationString; if (!Options.KeepFirstAttributeOnSameLine) { baseIndetationString = GetIndentString(xmlReader.Depth); } else { baseIndetationString = GetIndentString(xmlReader.Depth - 1) + string.Empty.PadLeft(elementName.Length + 2, ' '); } string pendingAppend; if (NoNewLineMarkupExtensionsList.Contains(attrInfo.MarkupExtension)) { pendingAppend = " " + attrInfo.ToSingleLineString(); } else { pendingAppend = attrInfo.ToMultiLineString(baseIndetationString); } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } attributeLines.Add(pendingAppend); } else { string pendingAppend = attrInfo.ToSingleLineString(); bool isAttributeCharLengthExceeded = (attributeCountInCurrentLineBuffer > 0 && Options.MaxAttributeCharatersPerLine > 0 && currentLineBuffer.Length + pendingAppend.Length > Options.MaxAttributeCharatersPerLine); bool isAttributeCountExceeded = (Options.MaxAttributesPerLine > 0 && attributeCountInCurrentLineBuffer + 1 > Options.MaxAttributesPerLine); bool isAttributeRuleGroupChanged = Options.PutAttributeOrderRuleGroupsOnSeparateLines && lastAttributeInfo != null && lastAttributeInfo.OrderRule.Group != attrInfo.OrderRule.Group; if (currentLineBuffer.Length > 0 && (forceLineBreakInAttributes || isAttributeCharLengthExceeded || isAttributeCountExceeded || isAttributeRuleGroupChanged)) { attributeLines.Add(currentLineBuffer.ToString()); currentLineBuffer.Length = 0; attributeCountInCurrentLineBuffer = 0; } currentLineBuffer.AppendFormat("{0} ", pendingAppend); attributeCountInCurrentLineBuffer++; } lastAttributeInfo = attrInfo; } if (currentLineBuffer.Length > 0) { attributeLines.Add(currentLineBuffer.ToString()); } for (int i = 0; i < attributeLines.Count; i++) { if (0 == i && Options.KeepFirstAttributeOnSameLine) { output .Append(' ') .Append(attributeLines[i].Trim()); // Align subsequent attributes with first attribute currentIndentString = GetIndentString(xmlReader.Depth - 1) + String.Empty.PadLeft(elementName.Length + 2, ' '); continue; } output .Append(Environment.NewLine) .Append(currentIndentString) .Append(attributeLines[i].Trim()); } _elementProcessStatusStack.Peek().IsMultlineStartTag = true; } // Determine if to put ending bracket on new line if (Options.PutEndingBracketOnNewLine && _elementProcessStatusStack.Peek().IsMultlineStartTag) { output .Append(Environment.NewLine) .Append(currentIndentString); hasPutEndingBracketOnNewLine = true; } } if (isEmptyElement) { if (hasPutEndingBracketOnNewLine == false && Options.SpaceBeforeClosingSlash) { output.Append(' '); } output.Append("/>"); _elementProcessStatusStack.Peek().IsSelfClosingElement = true; } else { output.Append(">"); } }