2009-09-15 23 views
12

benim nesne seri için bu yöntemi kullanıyorum:.NET ile xml serileştirmesinin <?xml ?> bölümünü nasıl denetlerim?

public static string XmlSerialize(object o) 
{ 
    var stringWriter = new StringWriter(); 
    var xmlSerializer = new XmlSerializer(o.GetType()); 
    xmlSerializer.Serialize(stringWriter, o); 
    string xml = stringWriter.ToString(); 
    stringWriter.Close(); 
    return xml; 
} 

Şöyle başlar XML yapar:

<?xml version="1.0" encoding="utf-16"?> 
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

Ama böyle bakmak istiyorum:

<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?> 
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

Peki, kodlamayı Windows-1252'ye nasıl değiştirebilirim ve bağımsız olarak ayarlıyorum = evet? Ayrıca, nesneyi xmlns değerini hariç tutmak için nasıl alabilirim?

this one gibi birkaç benzer soru gördüm, ama benim için daha basit olabileceğini umuyordum, belki bir yere bazı özellikler ayarlayarak?

Güncelleme 2: John'un cevabına ve yorumlarına baktıktan sonra bunu daha fazla düşünerek, sadece ikinci bir yöntem yapmaya karar verdim. Bu vahşice özel xml'in sadece bir vesileyle üçüncü bir taraf için yaratılmasının ilk etapta "XmlSerialize" gibi genel bir şey olarak adlandırılması gerektiğini düşünmüyorum.

Yani, bir XML belgesi alan bir ikinci yöntem oluşturulur ve ilk böyle bir ad elemanı kaldırır: o John'un kodu ile XML yazar, daha sonra

xElement.Attributes().Where(a => a.IsNamespaceDeclaration && a.Value == "http://www.w3.org/2001/XMLSchema").Remove(); 

.

new XDeclaration("1.0", "Windows-1252", "yes").ToString() 

Ve bu çirkin, ama tam olarak benim XML anlamak için bu 3 parti için gerekenleri beni alır: Nihayet bundan çıkışı sonrasında bu xml döndürür.

+0

Gerçekten, 'XmlTextReader' ve' XmlTextWriter' yerine 'XmlReader.Create' ve' XmlWriter.Create' kullanın. Ayrıca, bu şeyleri 'using' bloklarına koymanız gerekiyor. –

+0

Nihayetinde kodunuzla gittim. Ama sadece merak ediyorum, her şeyi kapattığım sürece, bu sadece blokları kullanmak kadar iyi değil mi? – Chris

+0

Hayır. Kullanma “blokları”, istisnalar gerçekleştiğinde bile nesnelerin atıldığından emin olun. –

cevap

25

bu deneyin ad, ama sonra, neden istiyorsun?


Güncelleme: Bu bir StringWriter her kullandığınızda, size kodlama seti ile bunun üstüne bir XmlWriter kullansalar bile, UTF-16 almak gibi görünüyor. Bir sonraki adım, bir MemoryStream'a yazmak olacaktır. Ama bu, neden bir dizge döndürmek istediğiniz sorusunu gündeme getiriyor. Örneğin, sadece arkanı dönüp dizeyi bir akışa gönderecekseniz, doğrudan bu akışa çıkış yapmalıyız. TextWriter için aynı.

+0

Bir API kullanıyorum ve xsd olayının orada olmaması gerektiğini belirttiler. Neden istemiyorlar ve neden görmezden gelemiyorlar ki, hiç bir fikrim yok. – Chris

+0

John, xml deklarasyonundan kurtulmak istemiyorum. Onu tutmak ve çıktılarını değiştirmek istiyorum. – Chris

+2

OmitXmlDeclaration = true'dan kurtulun ve bildirimi geri almalısınız. Xsd bildirimini ihlal ederse API kullanıcılarınızı ** gerçekten zor ** atmanız gerekir. Xsi: type belirtilmesi gerekiyorsa gerekli olacaktır. Eğer hepimiz standartlara uymazsak, yakında XML standart olmayacaktır. –

2

StringWriter yerine XmlTextWriter kullanabilirsiniz. Kodumun bir kısmından kodlama setinizle ilgili bir özüm. Bu xsd kurtulmak olmaz

public static string XmlSerialize(object o) 
{ 
    using (var stringWriter = new StringWriter()) 
    { 
     var settings = new XmlWriterSettings 
          { 
           Encoding = Encoding.GetEncoding(1252), 
           OmitXmlDeclaration = true 
          }; 
     using (var writer = XmlWriter.Create(stringWriter, settings)) 
     { 
      var xmlSerializer = new XmlSerializer(o.GetType()); 
      xmlSerializer.Serialize(writer, o); 
     } 
     return stringWriter.ToString(); 
    } 
} 

:

XmlTextWriter textWriter = new XmlTextWriter(stream, Encoding.GetEncoding(1252)); 
textWriter.Namespaces = false; 
+3

'XmlTextWriter 'kullanılmamalıdır. –

0

FWIW, XMLWriterSettings ile bir XmlWriter kullanarak çalışmak için kodlama var. İşte bir örnek:

... 
// My object type was from a class generated by xsd. 
XmlSerializer xms = new XmlSerializer(typeof(SomeType)); 
SomeType objSt; 
using(FileStream fs = new FileStream("C:\SomeFile.xml", FileMode.Open, FileAccess.Read)) 
{  
    using(XmlReader xr = XmlReader.Create(fs)) // Supposed to preserve encoding. 
    { 
    objSt = (SomeType)xms.Deserialize(xr); 
    }  
} 

... 
... // Do some stuff, change some attribute values. 
... 

XmlWriterSettings xsw= new XmlWriterSettings(); 
xsw.Indent= true; 
xsw.NewLineOnAttributes= true; 
xsw.Encoding = Encoding.GetEncoding(1252); 
using(XmlWriter xwXsw = XmlWriter.Create("C:\SomeFile_Changed.xml",xsw)) 
{  
    xms.Serialize(xwXsw, objSt); 
} 
... 
... // Finish up and get out. 
... 

Nedense, ben "hepsi XmlSerializer.Deserialize (XmlReader) MS yardımı göre beri bir kez sadece XmlSerializer nesnesini kullanarak ve bir TextWriter ile seri çalışmak için başardı XmlReader, XML belgesi tarafından belirtilen kodlamayı otomatik olarak algılar ve kullanır. " Sonra XmlWriterSettings ile oynamaya başladım ve bir şey kırdım ....

+0

FileStream, 'XmlReader' ve' XmlWriter '' i '' '' 'bloklarına yerleştirmemeniz için bir gecikti -1. –

+0

Serin - ama yorum açıkça "istisna taşıma veya" kullanarak "" belirtir. Uzun zaman önce neden böyle yaptığımı bilmiyorum. Duygularını incitmek istemedin :) – GTAE86

+0

Hangi yoruma atıfta bulunuyorsun? –

İlgili konular