|
/* Copyright (c) 2006 notmasteryet */
using System;
using System.Xml;
namespace XmlChunk
{
/// <summary>
/// XmlChunkWriter can be created using XmlWriter. It can be used
/// as standalone XmlWriter, e.g. to perform serialization of the
/// objects. When XmlChunkWriter is closed, main XmlWriter is ready
/// to continue write XML data. Using of XmlChunkWriter helps format
/// data is same manner and avoid writing of xml declaration
/// instruction in the middle of XML.
/// </summary>
public class XmlChunkWriter : XmlWriter
{
private const string XmlnsPrefix = "xmlns";
private const string XmlnsXsiName = "xsi";
private const string XmlnsXsdName = "xsd";
private XmlWriter baseWriter;
private bool skipXsiNsAttributes;
private int depth;
private State state;
/// <summary>
/// Contains base XmlWriter
/// </summary>
public XmlWriter BaseWriter
{
get
{
if (state == State.Completed)
throw new InvalidOperationException(Properties.Resources.WriterIsClosed);
return baseWriter;
}
}
/// <summary>
/// Creates writer
/// </summary>
/// <param name="writer">Base writer</param>
public XmlChunkWriter(XmlWriter writer) : this(writer, true)
{
}
/// <summary>
/// Creates writer
/// </summary>
/// <param name="writer">Base writer</param>
/// <param name="skipXsiNsAttributes">Root xmlns:xsi and xmlns:xsd attributes will be removed if true</param>
public XmlChunkWriter(XmlWriter writer, bool skipXsiNsAttributes)
{
if (writer == null)
throw new ArgumentNullException("writer");
this.baseWriter = writer;
this.skipXsiNsAttributes = skipXsiNsAttributes;
this.depth = 0;
this.state = State.Idle;
}
public override void Close()
{
BaseWriter.Flush();
state = State.Completed;
}
public override void Flush()
{
BaseWriter.Flush();
}
public override string LookupPrefix(string ns)
{
return BaseWriter.LookupPrefix(ns);
}
public override void WriteBase64(byte[] buffer, int index, int count)
{
BaseWriter.WriteBase64(buffer, index, count);
}
public override void WriteCData(string text)
{
BaseWriter.WriteCData(text);
}
public override void WriteCharEntity(char ch)
{
if (state == State.SkipAttribute) return;
BaseWriter.WriteCharEntity(ch);
}
public override void WriteChars(char[] buffer, int index, int count)
{
if (state == State.SkipAttribute) return;
BaseWriter.WriteChars(buffer, index, count);
}
public override void WriteComment(string text)
{
BaseWriter.WriteComment(text);
}
public override void WriteDocType(string name, string pubid, string sysid, string subset)
{
}
public override void WriteEndAttribute()
{
if (state != State.SkipAttribute)
{
BaseWriter.WriteEndAttribute();
}
else
state = State.InProcess;
}
public override void WriteEndDocument()
{
}
public override void WriteEndElement()
{
BaseWriter.WriteEndElement();
--depth;
}
public override void WriteEntityRef(string name)
{
if (state == State.SkipAttribute) return;
BaseWriter.WriteEntityRef(name);
}
public override void WriteFullEndElement()
{
BaseWriter.WriteFullEndElement();
--depth;
}
public override void WriteProcessingInstruction(string name, string text)
{
BaseWriter.WriteProcessingInstruction(name, text);
}
public override void WriteRaw(string data)
{
BaseWriter.WriteRaw(data);
}
public override void WriteRaw(char[] buffer, int index, int count)
{
BaseWriter.WriteRaw(buffer, index, count);
}
protected virtual bool IsXsiAttribute(string prefix, string localName, string ns)
{
return prefix == XmlnsPrefix &&
(localName == XmlnsXsiName || localName == XmlnsXsdName);
}
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
if (depth == 1 && skipXsiNsAttributes && IsXsiAttribute(prefix ,localName, ns))
{
// skiping attribute with namespace definition in root node
state = State.SkipAttribute;
return;
}
BaseWriter.WriteStartAttribute(prefix, localName, ns);
}
public override void WriteStartDocument(bool standalone)
{
}
public override void WriteStartDocument()
{
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
BaseWriter.WriteStartElement(prefix, localName, ns);
state = State.InProcess;
++depth;
}
public override WriteState WriteState
{
get
{
switch(state)
{
case State.Idle:
return WriteState.Start;
default:
case State.InProcess:
return BaseWriter.WriteState;
case State.SkipAttribute:
return WriteState.Attribute;
case State.Completed:
return WriteState.Closed;
}
}
}
public override void WriteString(string text)
{
if (state == State.SkipAttribute) return;
BaseWriter.WriteString(text);
}
public override void WriteSurrogateCharEntity(char lowChar, char highChar)
{
if (state == State.SkipAttribute) return;
BaseWriter.WriteSurrogateCharEntity(lowChar, highChar);
}
public override void WriteWhitespace(string ws)
{
BaseWriter.WriteWhitespace(ws);
}
private enum State
{
Idle,
InProcess,
SkipAttribute,
Completed
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.