c#,XML如何循环使用XMLNode.SelectSingleNode获取的XML节点

时间:2016-04-12 18:59:23

标签: c# xml

我有这个类代表我的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。

感谢您的时间。

2 个答案:

答案 0 :(得分:1)

您可以使用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);
    }
}

DotNetFiddle

答案 1 :(得分:1)

您可以使用以下扩展方法将XmlSerializerXmlNodeReader合并,直接从您选择的public class Solution { public ArrayList<ArrayList<Integer>> generate(int a) { ArrayList<Integer> internal = new ArrayList<Integer>(); ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); for(int i = 0 ; i < a ; i++) { internal.clear(); internal.add(1); for(int j = 0 ; j < i ; j++ ) { internal.add(internal.get(j) * (i - j)/(j + 1)); } result.add(internal); } return result; } } 反序列化:

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)); } } } 添加extension methodXmlNode会将所选节点的XmlSerializer deserialize调用到通用类型T的实例。

然后做:

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

与:

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

在您的情况下,TestCase类的预期根元素名称(<TestCase>)与实际节点名称匹配。如果节点名称与预期的根元素名称不匹配,您可以按照XmlSerializer Performance Issue when Specifying XmlRootAttribute中的说明告诉XmlSerializer预期不同的根名称。