Dam*_*ian 7 xml silverlight windows-phone-7
我在WP7上加载XML,我发现如果我在XML声明和doctype之间没有换行符,即使我忽略了doctype,我也会得到一个InvalidOperationException.在桌面上我没有这样的错误.
我的代码:
private static void Example()
{
const string works =
@"<?xml version=""1.0""?>
<!DOCTYPE example SYSTEM ""http://example.com/example.dtd""><hello></hello>";
const string fails =
@"<?xml version=""1.0""?><!DOCTYPE example SYSTEM ""http://example.com/example.dtd""><hello></hello>";
var textReader = new StringReader(works);
var xmlReaderSettings = new XmlReaderSettings {DtdProcessing = DtdProcessing.Ignore,};
var xmlReader = XmlReader.Create(textReader, xmlReaderSettings);
XDocument.Load(xmlReader); // No problem here
textReader = new StringReader(fails);
xmlReader = XmlReader.Create(textReader, xmlReaderSettings);
XDocument.Load(xmlReader); // Fails here
}
Run Code Online (Sandbox Code Playgroud)
第二个XDocument.Load失败并出现InvalidOperationException,并且消息XmlReader不应位于XmlDeclaration类型的节点上.唯一的区别是第二种情况下没有新线.
有没有人见过这个,并找到了解决方法?这适用于桌面btw - 在WP7上失败.在我的实际情况中,我正在从流中读取XML,因此在正确的位置手动注入新行并不是那么容易.
达米安
现在我已经实现了一个注入 NewLine 的 TextReader 包装器。我将其包含在这里,以防有人发现它有用,也以防有人有更优雅的解决方案 - 如果是这样,请发表评论!
它仅依赖于 XmlReader 调用 Read(...) 方法来读取数据 - 否则它会抛出 NotImplementedException。
在上面的示例中,您将像这样使用它:
textReader = new NewlineAfterXmlDeclReader(new StringReader(fails));
Run Code Online (Sandbox Code Playgroud)
这是实施
class NewlineAfterXmlDeclReader : TextReader
{
private const int InitialChunkSize = 80;
private const string SearchText = "?><!" + "DOCTYPE"; //concatenation injected for readability in SO purposes only
private static readonly string ReplaceText = "?>" + Environment.NewLine + "<!" + "DOCTYPE";
private readonly TextReader _wrappedReader;
private TextReader _firstChunkReader;
public NewlineAfterXmlDeclReader(TextReader wrappedReader)
{
_wrappedReader = wrappedReader;
var initialChunk = new char[InitialChunkSize];
var count = _wrappedReader.Read(initialChunk, 0, InitialChunkSize);
var initialChunkString = new String(initialChunk, 0, count);
_firstChunkReader = new StringReader(initialChunkString.Replace(SearchText, ReplaceText));
}
public override int Read(char[] buffer, int index, int count)
{
var firstChunkReadCount = 0;
if (_firstChunkReader != null)
{
firstChunkReadCount = _firstChunkReader.ReadBlock(buffer, index, count);
if (firstChunkReadCount == count) return firstChunkReadCount;
_firstChunkReader = null;
index += firstChunkReadCount;
count -= firstChunkReadCount;
}
return firstChunkReadCount + _wrappedReader.Read(buffer, index, count);
}
public override void Close()
{
_wrappedReader.Close();
}
protected override void Dispose(bool disposing)
{
_wrappedReader.Dispose();
}
public override int Peek() { throw new NotImplementedException(); }
public override int Read() { throw new NotImplementedException(); }
public override string ReadToEnd() { throw new NotImplementedException(); }
public override int ReadBlock(char[] buffer, int index, int count) { throw new NotImplementedException(); }
public override string ReadLine() { throw new NotImplementedException(); }
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
555 次 |
最近记录: |