簡體   English   中英

c#,XML如何在通過XMLNode.SelectSingleNode獲取的XML節點之間循環

[英]c#, XML How to cycle through an XML node fetched with XMLNode.SelectSingleNode

我有這個類,它代表XML中的一個節點TestCase:

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; }   

}

我使用XmlNode.SelectSingleNode來獲取XML中的特定節點。 對於信息,如果有問題,則沒有重復的節點(沒有具有相同名稱屬性的節點)。

到目前為止,我有以下代碼:

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;

    }

但是,此代碼根本無法伸縮,如果我更改類結構,則需要更改功能,因為類的每個元素都在其中進行了硬編碼。

這是一個廣泛的要求,但是我該如何編寫此函數,因此,如果在TestCase的類定義中添加或刪除字符串,則不必更改FetchNode函數。

感謝您的時間。

您可以使用XmlSerializer.Deserialize

例:

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

點網提琴

您可以使用以下擴展方法將XmlSerializerXmlNodeReader結合使用,從而直接從所選XmlNode反序列化:

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

這將擴展方法添加到XmlNode ,該方法調用XmlSerializer將選定的節點反序列化為通用類型T的實例。

然后做:

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

等同於:

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

在您的情況下,您的TestCase類的預期根元素名稱(即<TestCase> )與實際節點名稱匹配。 如果節點名稱與期望的根元素名稱不匹配,則可以在指定XmlRootAttribute時遵循XmlSerializer性能問題中的說明,告訴XmlSerializer期望使用不同的根名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM