我有一个包含(XML片段)文档的IObservable<string>
。我想把一个变成另一个。例如,假设我有从我的IObservable<string>
推送的以下片段(每行包含一个片段):
<?xml version=
"1.0" ?>
<testXml></test
Xml><?xml version="1.0"
?><otherXml /><?xm
如何将其转换为IObservable<XDocument>
以获取以下文档:
<?xml version="1.0"?><testXml />
<?xml version="1.0"?><otherXml />
我一直在考虑将IObservable<string>
移交给某些阻止TextReader
实施,但我认为应该有一个更聪明的解决方案。
答案 0 :(得分:4)
这个怎么样:
IObservable<string> splitXmlTokensIntoSeparateLines(string s)
{
// Here, you need to split tokens into separate lines (where 'token'
// is the beginning of an Xml element). This makes it easier down
// the line for the TakeWhile operator.
return new[] { firstPart, secondPart, etc }.ToObservable();
}
bool doesTokenTerminateDocument(string s)
{
// Here, you should return whether the XML represents the end of one
// document
}
var xmlDocuments = stringObservable
.SelectMany(x => splitXmlTokensIntoSeparateLines(x))
.TakeWhile(x => doesTokenTerminateDocument(x))
.Aggregate(new StringBuilder(), (acc, x), acc.Append(x))
.Select(x => {
var ret = new XDocument();
ret.Parse(x.ToString());
return ret;
})
.Repeat()
.TakeUntil(stringObservable.Aggregate(0, (acc, _) => acc));
TakeUntil是一个让它正确终止的黑客 - 基本上,Repeat会继续重新订阅,除非我们在stringObservable完成时告诉它完成停止它。
答案 1 :(得分:0)
您无法使用Select
运算符的任何原因?
var xmlObs = stringObs.Select(s => {
var x = new XDocument();
x.Parse(s);
return x;
});