您可以将XmlReader 子类化以“过滤”掉不需要的元素,然后将XmlDocument.Load() 与您的阅读器一起使用,而不是让它自己创建。
请注意,这将仅排除有问题的标签的 值:如果您在 Read() 循环中放置断点,您会发现 <foo>bar</foo> 分为三个部分:@987654324 @ 有没有值的 NodeType 元素,“bar”有 NodeType Text,有一个空的 LocalName,</foo> 是没有值的 NodeType EndElement。如果“bar”超过限制长度,下面的“过滤器”会将<foo>bar</foo> 变成<foo></foo> 要根据“bar”的长度排除所有<foo>bar</foo>,您必须向前看。可行,但可能不值得你花时间。希望这不是这里的要求。
这个类的替代(或添加)可能是一个带有Func<string, string> 的版本,每个Value 都通过:s => (s.Length > MAX_LEN) ? "" : s。
另外,据我所知,XmlTextReaderImpl(_reader 的实际类型)可能会缓存整个文本并影响您的性能。您可能还必须为这件事写下自己的胆量。
public class FilteredXmlReader : XmlReader
{
public Func<XmlReader, bool> Filter;
private XmlReader _reader;
private FilteredXmlReader(TextReader input, Func<XmlReader, bool> filterProc)
{
Filter = filterProc;
_reader = XmlReader.Create(input);
}
public static new XmlReader Create(TextReader input, Func<XmlReader, bool> filterProc)
{
return new FilteredXmlReader(input, filterProc);
}
public override bool Read()
{
var b = _reader.Read();
while (!(bool)Filter?.Invoke(_reader))
{
b = _reader.Read();
}
return b;
}
#region Wrapper Boilerplate
public override XmlNodeType NodeType => _reader.NodeType;
public override string LocalName => _reader.LocalName;
public override string NamespaceURI => _reader.NamespaceURI;
public override string Prefix => _reader.Prefix;
public override string Value => _reader.Value;
public override int Depth => _reader.Depth;
public override string BaseURI => _reader.BaseURI;
public override bool IsEmptyElement => _reader.IsEmptyElement;
public override int AttributeCount => _reader.AttributeCount;
public override bool EOF => _reader.EOF;
public override ReadState ReadState => _reader.ReadState;
public override XmlNameTable NameTable => _reader.NameTable;
public override string GetAttribute(string name) => _reader.GetAttribute(name);
public override string GetAttribute(string name, string namespaceURI) => _reader.GetAttribute(name, namespaceURI);
public override string GetAttribute(int i) => _reader.GetAttribute(i);
public override string LookupNamespace(string prefix) => _reader.LookupNamespace(prefix);
public override bool MoveToAttribute(string name) => _reader.MoveToAttribute(name);
public override bool MoveToAttribute(string name, string ns) => _reader.MoveToAttribute(name, ns);
public override bool MoveToElement() => _reader.MoveToElement();
public override bool MoveToFirstAttribute() => _reader.MoveToFirstAttribute();
public override bool MoveToNextAttribute() => _reader.MoveToNextAttribute();
public override bool ReadAttributeValue() => _reader.ReadAttributeValue();
public override void ResolveEntity() => _reader.ResolveEntity();
#endregion Wrapper Boilerplate
}
用法:
var xml = "<test />";
XmlDocument doc = new XmlDocument();
XmlReader rdr = FilteredXmlReader.Create(new System.IO.StringReader(xml),
r => r?.Value.Length < 20);
var filteredXML = doc.OuterXml;