2016-04-12 21 views
0

benim XML'inde bir düğüm TestCase temsil bu sınıf var: C#, XML Nasıl XMLNode.SelectSingleNode ile getirilen bir XML düğümü üzerinden döngüsü için

public class TestCase 
{ 
    [XmlAttribute("name")] 
    public string name { get; set; } 
    public string version { get; set; } 
    public string verdict { get; set; } 
    public string objective { get; set; } 
    public string criteria { get; set; } 
    public string issue { get; set; } 
    public string clientcomments { get; set; } 
    public string authoritycomments { get; set; } 
    public string sdk { get; set; } 

} 

ben belirli bir düğüm getirmek için XmlNode.SelectSingleNode kullanmak benim XML. Bilgi için, önemli olan düğümler (aynı isim niteliğine sahip düğüm yok) yoktur.

public static TestCase FetchNode(string NodeName, string Path) 
    { 
     TestCase testcase = new TestCase(); 
     string[] attr = { "name", "version", "verdict", "objective", "criteria" 
       , "issue", "clientcomments", "authoritycomments", "sdk" }; 
     string[] attrval = { null, null,null,null,null,null,null,null,null}; 

     XmlDocument doc = new XmlDocument(); 
     doc.Load(Path); 

     XmlNode node = doc.SelectSingleNode("/TestsList/TestCase[@name='" + NodeName + "']"); 

     for (var i = 0; i == attr.Length - 1;i++) 
     { 
      attrval[i] = node[attr[i]].InnerText; 
     } 

     testcase.name = attrval[0]; 
     testcase.version = attrval[1]; 
     testcase.verdict = attrval[2]; 
     testcase.objective = attrval[3]; 
     testcase.criteria = attrval[4]; 
     testcase.issue = attrval[5]; 
     testcase.clientcomments = attrval[6]; 
     testcase.authoritycomments = attrval[7]; 
     testcase.sdk = attrval[8]; 

     return testcase; 

    } 

Ancak, bu kod benim sınıf yapısını değiştirmek, ben sınıfın her elemanı, çünkü işlevini değiştirmek gerekir, hiç ölçeklenebilir değildir:

Şimdiye kadar, bu kod var kodlanmış.

Bu geniş bir sorundur, ancak bu işlevi nasıl yazabilirim, böylece TestCase sınıf tanımında bir dize ekler veya çıkarırsam, FetchNode işlevini değiştirmem gerekir.

Zaman ayırdığınız için teşekkür ederiz.

cevap

1

Şunları kullanabilirsiniz XmlSerializer.Deserialize

Örnek:

using System; 
using System.IO; 
using System.Xml; 
using System.Xml.Serialization; 

public class TestCase 
{ 
    [XmlAttribute("name")] 
    public string name { get; set; } 
    public string version { get; set; } 
    public string verdict { get; set; } 
    public string objective { get; set; } 
    public string criteria { get; set; } 
    public string issue { get; set; } 
    public string clientcomments { get; set; } 
    public string authoritycomments { get; set; } 
    public string sdk { get; set; } 
} 

public class Program 
{ 
    public const string XML = @" 
<TestCase name='TicketName'> 
    <name>Jon Nameson</name> 
    <version>10.1</version> 
    <verdict>High</verdict> 
</TestCase> 
"; 

    public static void Main() 
    { 
     var doc = new XmlDocument(); 
     doc.LoadXml(XML); 

     var node = doc.SelectSingleNode("/TestCase"); 

     var serializer = new XmlSerializer(typeof(TestCase)); 

     var testcase = serializer.Deserialize(new StringReader(node.OuterXml)) as TestCase; 

     Console.WriteLine(testcase.name); 
     Console.WriteLine(testcase.version); 
     Console.WriteLine(testcase.verdict); 
    } 
} 

DotNetFiddle

+0

Çok fazla değişiklik olmadan iyi çalıştı. Teşekkür ederim. –

1
Sen doğrudan serisini

senin şu uzatma yöntemi kullanılarak XmlNodeReader ile XmlSerializer birleştirerek XmlNode selected:

public static class XmlNodeExtensions 
{ 
    public static T Deserialize<T>(this XmlNode element, XmlSerializer serializer = null) 
    { 
     using (var reader = new ProperXmlNodeReader(element)) 
      return (T)(serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader); 
    } 

    class ProperXmlNodeReader : XmlNodeReader 
    { 
     // Bug fix from https://stackoverflow.com/questions/30102275/deserialize-object-property-with-stringreader-vs-xmlnodereader 
     public ProperXmlNodeReader(XmlNode node) 
      : base(node) 
     { 
     } 

     public override string LookupNamespace(string prefix) 
     { 
      return NameTable.Add(base.LookupNamespace(prefix)); 
     } 
    } 
} 

Bu extension method genel türü T örneğine XmlSerializer seçilen düğüm deserialize için çağırır olan XmlNode ekler.

Sonra yapın: özdeştir

var testcase = node.Deserialize<TestCase>(); 

için: Senin durumunda

var testcase = XmlNodeExtensions.Deserialize<TestCase>(node); 

sizin TestCase sınıfının, beklenen kök öğesi adı yani <TestCase> gerçek düğüm adını eşleşir. Düğüm adı beklenen kök öğe adıyla eşleşmiyorsa, 'daki yönergeleri izleyerek farklı bir kök adı beklemesini XmlSerializer söyleyebilirsiniz.

+0

Detaylı yanıt için teşekkürler. Benim anlayışım o kadar gelişmiş değil, bu yüzden bana sağladığınız kodun tam olarak ne olduğundan emin değilim. Bana kodun kısa bir açıklamasını verir misiniz? Teşekkürler! –

+0

@JephGagnon - Kısa bir açıklama ekledim, ama bilmen gereken şeyden emin değilim. – dbc

+0

Tam olarak yaptığınız şeylerin genel bir anlayışıydı. Sağladığınız bağlantı bana daha fazla bilgi veriyor. Negorath cevabını cevap olarak işaretledim çünkü ne yapıldığını anlayabiliyorum, ama kesinlikle bu yöntemi deneyeceğim (ve daha da önemlisi anlayacağım). Teşekkür ederim. –

İlgili konular