Exemplo n.º 1
0
        private void InsertNewlineToUnderlyingStream(PauseableWriteableStream writerStream, [NotNull] XmlStreamFormatterContext context)
        {
            writerStream.WriteByte(13);
            writerStream.WriteByte(10);

            for (var i = 0; i < context.CurrentElementDepth; i++)
            {
                writerStream.Write(context.IndentByteSequence, 0, context.IndentByteSequence.Length);
            }
        }
Exemplo n.º 2
0
        private bool OnCopyCallback(
            XmlNodeType nodeType,
            XmlReader xmlReader,
            XmlWriter xmlWriter,
            PauseableWriteableStream writerStream,
            [NotNull] XmlStreamFormatterOptions options,
            [NotNull] XmlStreamFormatterContext context)
        {
            if (!options.WrapLongElementLines)
            {
                return(true);
            }

            if (nodeType == XmlNodeType.Element)
            {
                context.CurrentLineLength =
                    xmlReader.Prefix.Length                            // prefix - if any
                    + (string.IsNullOrEmpty(xmlReader.Prefix) ? 0 : 1) // colon between prefix and local name, if any
                    + xmlReader.LocalName.Length                       // local name
                    + 1;                                               // opening triangular brace
                context.CurrentElementDepth++;
                return(true);
            }

            if (nodeType == XmlNodeType.EndElement)
            {
                context.CurrentAttributeCountOnElement = 0;
                context.CurrentLineLength = null;
                context.CurrentElementDepth--;
                return(true);
            }

            if (nodeType == XmlNodeType.Attribute)
            {
                context.CurrentAttributeCountOnElement++;
                Debug.Assert(context.CurrentLineLength.HasValue, "_currentLineLength cannot be null at attribute");

                // we want the underlying writer to think the attributes have been written, even though we will write them out "raw"
                // to the underlying stream, so we will "pause" the underlying stream, writer the xmlns attribute, and resume. The writer thinks
                // the attribute has been written, but it doesn't appear in the output!

                // This is especially important of xmlns attributes as if we don't write these out, the writer won't think they've has been written
                // and will start appending namespace declarations to child nodes explicitly as it encounters nodes that use them.

                xmlWriter.Flush();
                writerStream.PauseWriting();
                xmlWriter.WriteAttributeString(xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI, xmlReader.Value);
                xmlWriter.Flush();
                writerStream.ResumeWriting();

                xmlWriter.Flush();
                var sb = new StringBuilder();
                if (!string.IsNullOrEmpty(xmlReader.Prefix))
                {
                    sb.Append(xmlReader.Prefix);
                    sb.Append(":");
                }

                sb.AppendFormat(@"{0}=""{1}""", xmlReader.LocalName, SecurityElement.Escape(xmlReader.Value));

                if (context.CurrentLineLength + sb.Length + 1 > options.MaxElementLineLength)
                {
                    InsertNewlineToUnderlyingStream(writerStream, context);

                    var attributeAsBytes = context.Encoding.GetBytes(sb.ToString());
                    writerStream.Write(attributeAsBytes, 0, attributeAsBytes.Length);

                    context.CurrentLineLength = sb.Length;

                    if (sb.Length > options.MaxElementLineLength &&
                        context.CurrentAttributeCountOnElement < xmlReader.AttributeCount)
                    {
                        // this single attribute itself was bigger than the line length, and there are more attributes remaining.
                        // Insert another newline.
                        InsertNewlineToUnderlyingStream(writerStream, context);
                        context.CurrentLineLength = 0;
                    }

                    return(false);
                }
                else
                {
                    if (context.CurrentLineLength != 0)
                    {
                        sb.Insert(0, " ");
                    }
                    var attributeAsBytes = context.Encoding.GetBytes(sb.ToString());
                    writerStream.Write(attributeAsBytes, 0, attributeAsBytes.Length);

                    context.CurrentLineLength += sb.Length;
                    return(false);
                }
            }

            return(true);
        }