自定义xmlWriter跳过某个元素?

我正在实现一个自定义xmlwriter,我想省略任何具有特定名称的元素,如

我该怎么做呢? 我觉得我可能需要像这样覆盖WriteStartElement方法:

 public override void WriteStartElement(string prefix, string localName, string ns) { if (localName.Equals("ABC")) { return; } base.WriteStartElement(prefix, localName, ns); } 

我是否还需要覆盖WriteEndElement方法? 如何告诉WriteEndElement方法跳过编写结束标记? 在WriteEndElement方法中似乎没有可以检查的localName引用…?

在我之前写的一些示例代码中找到了这个。 它维护一个下推式堆栈,以确定是否要编写元素结束,这是您需要执行的操作:

 public class ElementSkippingXmlTextWriter : XmlWriterProxy { readonly Stack stack = new Stack(); readonly Func filter; readonly Func nameEditor; readonly bool filterChildren; public ElementSkippingXmlTextWriter(XmlWriter writer, Func filter, bool filterChildren) : this(writer, filter, null, filterChildren) { } public ElementSkippingXmlTextWriter(XmlWriter writer, Func filter, Func nameEditor, bool filterChildren) : base(writer) { this.filter = filter ?? delegate { return true; }; this.nameEditor = nameEditor ?? delegate(string localName, string ns, int depth) { return localName; }; this.filterChildren = filterChildren; } protected override bool IsSuspended { get { if (filterChildren) { if (!stack.All(b => b)) return true; } else { if (stack.Count > 0 && !stack.Peek()) return true; } return base.IsSuspended; } } public override void WriteStartElement(string prefix, string localName, string ns) { var write = filter(localName, ns, stack.Count); var newLocalName = nameEditor(localName, ns, stack.Count); if (write) base.WriteStartElement(prefix, newLocalName, ns); stack.Push(write); } public override void WriteEndElement() { if (stack.Pop()) base.WriteEndElement(); } } public class XmlWriterProxy : XmlWriter { readonly XmlWriter baseWriter; public XmlWriterProxy(XmlWriter baseWriter) { if (baseWriter == null) throw new ArgumentNullException(); this.baseWriter = baseWriter; } protected virtual bool IsSuspended { get { return false; } } public override void Close() { baseWriter.Close(); } 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) { if (IsSuspended) return; baseWriter.WriteBase64(buffer, index, count); } public override void WriteCData(string text) { if (IsSuspended) return; baseWriter.WriteCData(text); } public override void WriteCharEntity(char ch) { if (IsSuspended) return; baseWriter.WriteCharEntity(ch); } public override void WriteChars(char[] buffer, int index, int count) { if (IsSuspended) return; baseWriter.WriteChars(buffer, index, count); } public override void WriteComment(string text) { if (IsSuspended) return; baseWriter.WriteComment(text); } public override void WriteDocType(string name, string pubid, string sysid, string subset) { if (IsSuspended) return; baseWriter.WriteDocType(name, pubid, sysid, subset); } public override void WriteEndAttribute() { if (IsSuspended) return; baseWriter.WriteEndAttribute(); } public override void WriteEndDocument() { if (IsSuspended) return; baseWriter.WriteEndDocument(); } public override void WriteEndElement() { if (IsSuspended) return; baseWriter.WriteEndElement(); } public override void WriteEntityRef(string name) { if (IsSuspended) return; baseWriter.WriteEntityRef(name); } public override void WriteFullEndElement() { if (IsSuspended) return; baseWriter.WriteFullEndElement(); } public override void WriteProcessingInstruction(string name, string text) { if (IsSuspended) return; baseWriter.WriteProcessingInstruction(name, text); } public override void WriteRaw(string data) { if (IsSuspended) return; baseWriter.WriteRaw(data); } public override void WriteRaw(char[] buffer, int index, int count) { if (IsSuspended) return; baseWriter.WriteRaw(buffer, index, count); } public override void WriteStartAttribute(string prefix, string localName, string ns) { if (IsSuspended) return; baseWriter.WriteStartAttribute(prefix, localName, ns); } public override void WriteStartDocument(bool standalone) { baseWriter.WriteStartDocument(standalone); } public override void WriteStartDocument() { baseWriter.WriteStartDocument(); } public override void WriteStartElement(string prefix, string localName, string ns) { if (IsSuspended) return; baseWriter.WriteStartElement(prefix, localName, ns); } public override WriteState WriteState { get { return baseWriter.WriteState; } } public override void WriteString(string text) { if (IsSuspended) return; baseWriter.WriteString(text); } public override void WriteSurrogateCharEntity(char lowChar, char highChar) { if (IsSuspended) return; baseWriter.WriteSurrogateCharEntity(lowChar, highChar); } public override void WriteWhitespace(string ws) { if (IsSuspended) return; baseWriter.WriteWhitespace(ws); } } 

它会像往常一样通过调用XmlWriter.Create()包装一个XmlWriter ,并过滤filter委托返回false元素(以及可选的子XmlWriter.Create()

注意 – 未经过充分测试。