2013-12-18 27 views
6

Örneğin, 4 setin (A, B, C, D) üyeleri arasındaki permutasyonu temsil eden bazı XML'lere sahibim. A = {A1, A2}, B = {B1}, C = {C1, C2} ve D = {D1, D2, D3} olduğunu varsayalım ancak mevcut XML normal değildir, çünkü bu üyeler her biri için düzenli olmayan şekilde birleştirilmiştir. Cevap. "set" Nitelik, setin ismini gösterir ve "üye" her setin her bir üyesini gösterir. Bu XML aşağıdaki gibi:XML Elements Normalleştirme

<root> 
    <phrase permutation=ABCD> 
     <ans number=1> 
      <word set=A member=A1/> 
      <word set=A member=A2/> 
      <word set=B member=B1/> 
      <word set=C member=C1/> 
      <word set=D member=D2/> 
     </ans> 
     <ans number=2> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C1/> 
      <word set=C member=C2/> 
      <word set=C member=C3/> 
      <word set=D member=D1/> 
      <word set=D member=D3/> 
     </ans> 
    </phrase> 
</root> 

ve her bir belirli bir cevapta bir permütasyon koymak istiyorum. Her cevap, A'nın bir üyesiyle sadece bir A ve Bitiş üyesi ile başlamalı ve aralarında sadece B ve C kümelerinin bir üyesini kullanmalıdır. örneğin A1A2B1C1D2 A1B1C1D2, A2B1C1D2 için ayrı olmalı cevaplamak ve A1B1C1C2C3D1D3 A1B1C1D1, A1B1C1D3, A1B1C2D1, A1B1C2D3, A1B1C3D1 ve A1B1C3D3 nihai XML ayrı olmalı cevap Böyle XML aşağıdaki gibi sever:

<root> 
    <phrase permutation=ABCD> 
     <ans number=1> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C1/> 
      <word set=D member=D2/> 
     </ans> 
     <ans number=2> 
      <word set=A member=A2/> 
      <word set=B member=B1/> 
      <word set=C member=C1/> 
      <word set=D member=D2/> 
     </ans> 
     <ans number=3> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C1/> 
      <word set=D member=D1/> 
      </ans> 
     <ans number=4> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C1/> 
      <word set=D member=D3/> 
      </ans> 
     <ans number=5> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C2/> 
      <word set=D member=D1/> 
     </ans> 
     <ans number=6> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C2/> 
      <word set=D member=D3/> 
     </ans> 
     <ans number=7> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C3/> 
      <word set=D member=D1/> 
     </ans> 
     <ans number=8> 
      <word set=A member=A1/> 
      <word set=B member=B1/> 
      <word set=C member=C3/> 
      <word set=D member=D3/> 
     </ans> 
    </phrase> 
</root> 

Sorumun umut Açık ol ve bana yardım edebilirsin. Teşekkürler

cevap

5

Tamam, her şeyden önce şunu unutmayın: XML özniteliklerinizin ayrılmamış olduğunu unutmayın, bu nedenle .NET'in standart XML işlemi kutunun dışında bunları okuyamaz - Ben sadece aşağıdaki çözümü yazmak için bunları düzelttim.

var original = XDocument.Parse(/* your XML as string */); 

var normalized = new XDocument(original); 

foreach (var phraseNode in normalized.Root.Elements("phrase")) 
{ 
    phraseNode.Elements().Remove(); 
    int ansNo = 1; 

    foreach(var answer in original.Root 
           .Elements("phrase") 
           .Single(p => p.Attribute("permutation").Value 
              == phraseNode.Attribute("permutation").Value) 
           .Elements("ans")) 
    { 
     var groupedWords = answer.Elements("word") 
           .GroupBy(w => w.Attribute("set").Value) 
           .ToArray(); 
     var newAnswers = groupedWords.Skip(1) 
            .Aggregate(
            groupedWords[0].Select(w => Enumerable.Repeat(w, 1)), 
            (combinations, newWords) => 
             combinations.Join(newWords, 
                  c => 1, 
                  w => 1, 
                  (c, w) => c.Concat(new[] { w }))); 
     foreach (var newAnswer in newAnswers) 
     { 
     var ansNode = new XElement("ans", new XAttribute("number", ansNo++)); 
     ansNode.Add(newAnswer.Select(w => new XElement(w)).ToArray()); 
     phraseNode.Add(ansNode); 
     } 
    } 
} 

XML için LINQ bilgisini bilmiyorsanız, bu ilk başta biraz korkutucu olabilir; umarım bir miktar hafif okuma veya ön bilgi ile daha karmaşık (elbette göreceli olarak konuşulur!) biti, permütasyonları yaratan asıl kod olabilir (newAnswers var başlatılan kısım) - ya bunu yüz değerinde alabilir ya da okuyabilirsiniz. LINQ'in nasıl çalıştığı hakkında biraz daha fazla.

Ayrıca - bunun akılda herhangi bir ağır hizmet optimizasyonu ile yazılmadığını lütfen unutmayın; % 99,99 vakada bu umarım bir sorun olmamalı.