2014-05-14 17 views
6

MusicXML dosyalarını dosyama yüklüyorum. Sorun:Seri hale getirilmeden önce XML dosyalarının türlerini nasıl ayırt edebilirim?

<?xml version="1.0" encoding='UTF-8' standalone='no' ?> 
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd"> 
<score-partwise version="2.0"> 
    <work>...</work> 
    ... 
</score-partwise> 

ve

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE score-timewise PUBLIC "-//Recordare//DTD MusicXML 2.0 Timewise//EN" "http://www.musicxml.org/dtds/timewise.dtd"> 
<score-timewise version="2.0"> 
    <work>...</work> 
    ... 
</score-timewise> 

deserializing için Kodum: Farklı kök düğümlerin (ve farklı bir yapıya) sahip iki “lehçeler”, timewise ve partwise vardır partwise skor şimdiye kadar geçerli:

using (var fileStream = new FileStream(openFileDialog.FileName, FileMode.Open)) 
{ 
    var xmlSerializer = new XmlSerializer(typeof(ScorePartwise)); 
    var result = (ScorePartwise)xmlSerializer.Deserialize(fileStream); 
} 

İki lehçeyi birbirinden ayırmanın en iyi yolu ne olurdu?

+0

xml dosyaları ne kadar büyük? – EkoostikMartin

+0

Bu gerçekten parçaya bağlı, dört sesleri ile Palestrina tarafından ortalama bir motet yaklaşık 12000 satır/300 KB var. Bütün bir senfoni kesinlikle bundan daha fazlasına sahip olacak. –

+1

Tamam, dosyanın 3. satırını bir dizeye yüklerim ve daha sonra bir parçacığı veya timewise'ı aramak için 'String.IndexOf()' yapardım, sonra hangi dosya türüyle uğraştığınızı bilirsiniz. doğru seri hale getirici. – EkoostikMartin

cevap

5

Burada, dosyayı ayrıştırmak türünü belirlemek için kök öğeyi okuyun ve serileştiriciye okumak için bir XDocument kullanarak bunu yapmak için bir yoldur.

var xdoc = XDocument.Load(filePath); 
Type type; 
if (xdoc.Root.Name.LocalName == "score-partwise") 
    type = typeof(ScorePartwise); 
else if (xdoc.Root.Name.LocalName == "score-timewise") 
    type = typeof(ScoreTimewise); 
else 
    throw new Exception(); 
var xmlSerializer = new XmlSerializer(type); 
var result = xmlSerializer.Deserialize(xdoc.CreateReader()); 
+1

Sadece ilk satırı kontrol etmek için tüm xml belgenin yüklenmesi, dosyanın en az 12000 satır olduğunu düşünürsek biraz yavaş olacaktır. – EkoostikMartin

+0

Yine de tüm dosyayı serpiştirerek okumak üzeresiniz. Okumak -> ilk satırı kontrol et -> bellek içi dosyayı serpiştiriciye göndermek çok kötü olamaz (bellek kullanımının çok kötü olduğu varsayılırsa; dosyada olması gereken onlarca MB veya daha az, ince). –

2

ben bir

using (var fileStream = new FileStream(openFileDialog.FileName, FileMode.Open)) 
{ 
    using (var xmlReader = XmlReader.Create(filStream)) 
    { 
    if (partwiseSerializer.CanDeserialize(xmlReader)) 
    { 
     var result = partwiseSerializer.Deserialize(xmlReader); 
    } 
    else 
    { 
     var result = timewiseSerializer.Deserialize(xmlReader); 
    } 
    } 
} 

üzerinde CanDeserialize yöntemini çağırır sadece bu iki olduğunu varsayarsak her iki serializers

var partwiseSerializer = new XmlSerializer(typeof(ScorePartwise)); 
var timewiseSerializer = new XmlSerializer(typeof(ScoreTimewise)); 

yaratacak Açıkçası bu bunu nasıl sadece bir fikirdir. Orada daha fazla seçenek vardı ya da uygulama tasarımına göre ben CanDeserialize çağırmak için daha sofistike bir şekilde kullanmak istiyorsunuz, ama bu yöntem bence anahtarıdır: XmlReader sınıfı burada

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.candeserialize.aspx

bulunabilir :

http://msdn.microsoft.com/en-us/library/System.Xml.XmlReader(v=vs.110).aspx

İlgili konular