2011-05-05 19 views
7

WP7'ye XML yüklüyorum ve XML bildirimi ve doctype arasında bir satır yoksa, görmezden geldiğim halde doctype, bir InvalidOperationException olsun. Masaüstünde böyle bir hata yok.InvalidOperationException wp7 üzerinde xml bildirimi ve doctype arasında bir CR olmayan XML okuma

Kodum:

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 
} 

ikinci XDocument.Load XmlReader tipi XmlDeclaration bir düğüme olmamalı bir ınvalidoperationexception ve mesajın başarısız olur. Tek fark, ikinci durumda yeni bir satır olmamasıdır.

Bunu daha önce görmüş ve bir çözüm bulmuş mu? Bu masaüstü btw üzerinde çalışıyor - sadece WP7'de başarısız oluyor. Gerçek vakamda XML'i bir akıştan okuyorum, bu yüzden yeni çizgiyi el ile doğru yere enjekte etmek o kadar kolay olmayacak.

Damian

şimdi yeni satır enjekte TextReader sarıcı uyguladık için
+0

Bunun için hiç hoş bir çözüm buldunuz mu? – mike

+0

Çözümümden daha iyi bir şey yok - XML'yi akışa almam gerekiyordu, çünkü büyük olabilirdi. Hepsini belleğe yüklemek benim için bir seçenek değildi. – Damian

+0

Lanet. Aslında XElement yerine XmlDocument sınıfına gitmeyi bitirdim. Çok daha iyi bir cehennem gibi görünüyor, XElement çocuk öğelerimi doğru şekilde tespit etmiyordu :( – mike

cevap

3

. Birinin yararlı bulması durumunda, ve birilerinin daha zarif bir çözümü olması durumunda buraya dahil ediyorum - eğer öyleyse lütfen yorum yapın!

Verileri okumak için yalnızca Oku (...) yöntemini çağırdığında XmlReader'a güvenir - aksi halde NotImplementedException atar.

Yukarıdaki örnekte böyle kullanmak istiyorum:

textReader = new NewlineAfterXmlDeclReader(new StringReader(fails)); 

Bu, bu zarif ama benim için çalıştı eğer emin değilim uygulama

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(); } 
} 
0

olduğunu. Ne olup bittiğine emin değilim, eğer google doğru hata mesajı ise bu tek sonuç! kusar

Kodu:

WebRequest request = (HttpWebRequest)WebRequest.Create(url); 
request.Timeout = (int)_Timeout.TotalMilliseconds; 

using (var resp = (HttpWebResponse)request.GetResponse()) 
{ 
    using (XmlReader reader = XmlTextReader.Create(resp.GetResponseStream())) 
    { 
    reader.Read(); 
    return (XElement)XElement.ReadFrom(reader); 
    } 
} 

Kod mutlu: bir dizeye yanıtı okuma ve işlev farklı bir şey yapar) (Parse o geçen nedense Yani

WebRequest request = (HttpWebRequest)WebRequest.Create(url); 
request.Timeout = (int)_Timeout.TotalMilliseconds; 

using (var resp = (HttpWebResponse)request.GetResponse()) 
{ 
    using (var responseStream = resp.GetResponseStream()) 
    { 
    using (var reader = new StreamReader(responseStream, Encoding.ASCII)) 
    { 
     string raw = reader.ReadToEnd(); 
     return (XElement)XElement.Parse(raw); 
    } 
    } 
} 

ReadFrom() işlevini ve bir akışı kullanmak. Potansiyel olarak Parse fonksiyonu biraz daha gevşek, ama daha fazla kazmadım.

İlgili konular