您可以创建棘手的 Stream,它在自定义位置模拟 Ducument 的 start 元素。它的代码非常粗糙,但它的工作原理
void Main()
{
var xml =
@"<Contacts><Contact><Name>Todd</Name><Email>todd@blah.com</Email></Contact><Contact>
<Name>Sarah1</Name>
<Email>sarah@blah.com</Email>
</Contact>
<Contact>
<Name>Sarah2</Name>
<Email>sarah@blah.com</Email>
</Contact>
</Contacts>";
var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));
ms.Position = 74;
var reader = XmlReader.Create(new CustomReader("<Contacts>",ms));
var xdoc = XDocument.Load(reader);
var contact = xdoc.Descendants("Contact").Select(x => x).ToArray();
contact.Dump();
}
public class CustomReader : Stream
{
private readonly string _element;
private readonly Stream _stream;
private int _offset;
public CustomReader(string element, Stream stream)
{
_element = element;
_stream = stream;
_offset = -element.Length;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override void Close()
{
_stream.Close();
base.Close();
}
public override void Flush()
{
throw new NotImplementedException();
}
public override long Length
{
get { throw new NotImplementedException(); }
}
public override long Position
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override int Read(byte[] buffer, int offset, int count)
{
if (count == 0) return 0;
if (_offset < 0)
{
var buf = Encoding.UTF8.GetBytes(_element);
Buffer.BlockCopy(buf, 0, buffer, offset, buf.Length);
_offset = 0;
return buf.Length;
}
return _stream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}