简体   繁体   中英

XML members initialization for XmlSerializer using C#

I have below XML and need to deserialized to get the value of "ThreadGroup.num_threads","ThreadGroup.ramp_time","HTTPSampler.path" and "HTTPSampler.domain".

    <TestPlan>
        <hashTree>
            <hashTree>
                <ThreadGroup>
                    <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
                    <stringProp name="ThreadGroup.num_threads">10</stringProp>
                    <stringProp name="ThreadGroup.ramp_time">1</stringProp>
                    <longProp name="ThreadGroup.start_time">1517853259000</longProp>
                    <longProp name="ThreadGroup.end_time">1517853259000</longProp>
                    <boolProp name="ThreadGroup.scheduler">false</boolProp>
                    <stringProp name="ThreadGroup.duration"></stringProp>
                    <stringProp name="ThreadGroup.delay"></stringProp>
                </ThreadGroup>
                <hashTree>
                    <hashTree>
                        <HTTPSamplerProxy>
                            <stringProp name="HTTPSampler.domain">www.abc.com/abc-service-api</stringProp>
                            <stringProp name="HTTPSampler.port"></stringProp>
                            <stringProp name="HTTPSampler.protocol"></stringProp>
                            <stringProp name="HTTPSampler.contentEncoding"></stringProp>
                            <stringProp name="HTTPSampler.path">/v1/test/test?debug=false</stringProp>
                            <stringProp name="HTTPSampler.method">GET</stringProp>
                            <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
                            <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
                            <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
                            <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
                            <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
                            <stringProp name="HTTPSampler.connect_timeout"></stringProp>
                            <stringProp name="HTTPSampler.response_timeout"></stringProp>
                        </HTTPSamplerProxy>
                    </hashTree>
                </hashTree>
            </hashTree>
        </hashTree>
    </TestPlan>

The code I am using mentioned below.

    public class xmlData
        {
            [Serializable, XmlRoot("jmeterTestPlan")]
            public partial class jmeterTestPlan
            {
                private jmeterTestPlanHashTree hashTreeField;
                /// <remarks/>
                public jmeterTestPlanHashTree hashTree
                {
                    get
                    {
                        return this.hashTreeField;
                    }
                    set
                    {
                        this.hashTreeField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTree
            {
                private jmeterTestPlanHashTreeHashTree hashTreeField;
                /// <remarks/>
                public jmeterTestPlanHashTreeHashTree hashTree
                {
                    get
                    {
                        return this.hashTreeField;
                    }
                    set
                    {
                        this.hashTreeField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTree
            {
                private jmeterTestPlanHashTreeHashTreeThreadGroup threadGroupField;
                private jmeterTestPlanHashTreeHashTreeHashTree hashTreeField;
                /// <remarks/>
                public jmeterTestPlanHashTreeHashTreeThreadGroup ThreadGroup
                {
                    get
                    {
                        return this.threadGroupField;
                    }
                    set
                    {
                        this.threadGroupField = value;
                    }
                }
                /// <remarks/>
                public jmeterTestPlanHashTreeHashTreeHashTree hashTree
                {
                    get
                    {
                        return this.hashTreeField;
                    }
                    set
                    {
                        this.hashTreeField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeThreadGroup
            {
                private object[] itemsField;
                /// <remarks/>
                [System.Xml.Serialization.XmlElementAttribute("boolProp", typeof(jmeterTestPlanHashTreeHashTreeThreadGroupBoolProp))]
                [System.Xml.Serialization.XmlElementAttribute("longProp", typeof(jmeterTestPlanHashTreeHashTreeThreadGroupLongProp))]
                [System.Xml.Serialization.XmlElementAttribute("stringProp", typeof(jmeterTestPlanHashTreeHashTreeThreadGroupStringProp))]
                public object[] Items
                {
                    get
                    {
                        return this.itemsField;
                    }
                    set
                    {
                        this.itemsField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeThreadGroupBoolProp
            {
                private string nameField;
                private bool valueField;
                /// <remarks/>
                [System.Xml.Serialization.XmlAttributeAttribute()]
                public string name
                {
                    get
                    {
                        return this.nameField;
                    }
                    set
                    {
                        this.nameField = value;
                    }
                }
                /// <remarks/>
                [System.Xml.Serialization.XmlTextAttribute()]
                public bool Value
                {
                    get
                    {
                        return this.valueField;
                    }
                    set
                    {
                        this.valueField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeThreadGroupLongProp
            {
                private string nameField;
                private ulong valueField;
                /// <remarks/>
                [System.Xml.Serialization.XmlAttributeAttribute()]
                public string name
                {
                    get
                    {
                        return this.nameField;
                    }
                    set
                    {
                        this.nameField = value;
                    }
                }
                /// <remarks/>
                [System.Xml.Serialization.XmlTextAttribute()]
                public ulong Value
                {
                    get
                    {
                        return this.valueField;
                    }
                    set
                    {
                        this.valueField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeThreadGroupStringProp
            {
                private string nameField;
                private string valueField;
                /// <remarks/>
                [System.Xml.Serialization.XmlAttributeAttribute()]
                public string name
                {
                    get
                    {
                        return this.nameField;
                    }
                    set
                    {
                        this.nameField = value;
                    }
                }
                /// <remarks/>
                [System.Xml.Serialization.XmlTextAttribute()]
                public string Value
                {
                    get
                    {
                        return this.valueField;
                    }
                    set
                    {
                        this.valueField = value;
                    }
                }
            }
            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeHashTree
            {
                private jmeterTestPlanHashTreeHashTreeHashTreeHashTree hashTreeField;
                /// <remarks/>
                public jmeterTestPlanHashTreeHashTreeHashTreeHashTree hashTree
                {
                    get
                    {
                        return this.hashTreeField;
                    }
                    set
                    {
                        this.hashTreeField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeHashTreeHashTree
            {
                private jmeterTestPlanHashTreeHashTreeHashTreeHashTreeHTTPSamplerProxy hTTPSamplerProxyField;
                /// <remarks/>
                public jmeterTestPlanHashTreeHashTreeHashTreeHashTreeHTTPSamplerProxy HTTPSamplerProxy
                {
                    get
                    {
                        return this.hTTPSamplerProxyField;
                    }
                    set
                    {
                        this.hTTPSamplerProxyField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeHashTreeHashTreeHTTPSamplerProxy
            {
                private object[] itemsField;
                /// <remarks/>
                [System.Xml.Serialization.XmlElementAttribute("boolProp", typeof(jmeterTestPlanHashTreeHashTreeHashTreeHashTreeHTTPSamplerProxyBoolProp))]
                [System.Xml.Serialization.XmlElementAttribute("stringProp", typeof(jmeterTestPlanHashTreeHashTreeHashTreeHashTreeHTTPSamplerProxyStringProp))]
                public object[] Items
                {
                    get
                    {
                        return this.itemsField;
                    }
                    set
                    {
                        this.itemsField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeHashTreeHashTreeHTTPSamplerProxyBoolProp
            {
                private string nameField;
                private bool valueField;
                /// <remarks/>
                [System.Xml.Serialization.XmlAttributeAttribute()]
                public string name
                {
                    get
                    {
                        return this.nameField;
                    }
                    set
                    {
                        this.nameField = value;
                    }
                }
                /// <remarks/>
                [System.Xml.Serialization.XmlTextAttribute()]
                public bool Value
                {
                    get
                    {
                        return this.valueField;
                    }
                    set
                    {
                        this.valueField = value;
                    }
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
            public partial class jmeterTestPlanHashTreeHashTreeHashTreeHashTreeHTTPSamplerProxyStringProp
            {
                private string nameField;
                private string valueField;
                /// <remarks/>
                [System.Xml.Serialization.XmlAttributeAttribute()]
                public string name
                {
                    get
                    {
                        return this.nameField;
                    }
                    set
                    {
                        this.nameField = value;
                    }
                }
                /// <remarks/>
                [System.Xml.Serialization.XmlTextAttribute()]
                public string Value
                {
                    get
                    {
                        return this.valueField;
                    }
                    set
                    {
                        this.valueField = value;
                    }
                }
            }


        }

the above code is giving required value with a lot of additional attributes value and the code seems lengthy too. However, I need those 4 value. Please suggest any better solution.

UPDATED (2018-09-10)

I've updated this to get it easy to use.

Before I started, I decided that you probably wanted the possibility of longProps in the HTTPSamplerProxy section. It also made the coding (much) easier and cleaner. I've tested it without any longProps just to make sure it worked with the existing XML the way you'd expect.

The original process

The updates to the original description are italicized

What I did was to use the standard XSD.exe tool to take your source XML file (with an extra longProp in the HTTPSamplerProxy section) and create an XSD. Then I used XSD.exe again to create a (very ugly) C# file. At that point, the root of the whole mess is the TestPlan class. Here's what XSD.exe produced (updated - the only change to the newly-emitted XSD.exe code was a namespace declaration at the top) :

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class hashTree {

    private hashTreeHTTPSamplerProxy[] hTTPSamplerProxyField;

    private hashTree[] hashTree1Field;

    private hashTreeThreadGroup[] threadGroupField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("HTTPSamplerProxy", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public hashTreeHTTPSamplerProxy[] HTTPSamplerProxy {
        get {
            return this.hTTPSamplerProxyField;
        }
        set {
            this.hTTPSamplerProxyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("hashTree")]
    public hashTree[] hashTree1 {
        get {
            return this.hashTree1Field;
        }
        set {
            this.hashTree1Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ThreadGroup", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public hashTreeThreadGroup[] ThreadGroup {
        get {
            return this.threadGroupField;
        }
        set {
            this.threadGroupField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class hashTreeHTTPSamplerProxy {

    private longProp[] longPropField;

    private stringProp[] stringPropField;

    private boolProp[] boolPropField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("longProp", IsNullable = true)]
    public longProp[] longProp {
        get {
            return this.longPropField;
        }
        set {
            this.longPropField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("stringProp", IsNullable = true)]
    public stringProp[] stringProp {
        get {
            return this.stringPropField;
        }
        set {
            this.stringPropField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("boolProp", IsNullable = true)]
    public boolProp[] boolProp {
        get {
            return this.boolPropField;
        }
        set {
            this.boolPropField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = true)]
public partial class longProp {

    private string nameField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = true)]
public partial class stringProp {

    private string nameField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = true)]
public partial class boolProp {

    private string nameField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class hashTreeThreadGroup {

    private stringProp[] stringPropField;

    private longProp[] longPropField;

    private boolProp[] boolPropField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("stringProp", IsNullable = true)]
    public stringProp[] stringProp {
        get {
            return this.stringPropField;
        }
        set {
            this.stringPropField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("longProp", IsNullable = true)]
    public longProp[] longProp {
        get {
            return this.longPropField;
        }
        set {
            this.longPropField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("boolProp", IsNullable = true)]
    public boolProp[] boolProp {
        get {
            return this.boolPropField;
        }
        set {
            this.boolPropField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class TestPlan {

    private object[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("boolProp", typeof(boolProp), IsNullable = true)]
    [System.Xml.Serialization.XmlElementAttribute("hashTree", typeof(hashTree))]
    [System.Xml.Serialization.XmlElementAttribute("longProp", typeof(longProp), IsNullable = true)]
    [System.Xml.Serialization.XmlElementAttribute("stringProp", typeof(stringProp), IsNullable = true)]
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

The rest of this is mostly new

The code emitted by XSD.exe creates a set of partial classes. I extended the partial classes in a few ways in a separate source file. But, before I started, I declared an interface and a static worker class.

public interface IGrouping {
    boolProp[] boolProp { get; }
    stringProp[] stringProp { get; }
    longProp[] longProp { get; }

    Dictionary<string, bool?> BoolProperties { get; }
    Dictionary<string, long?> LongProperties { get; }
    Dictionary<string, string> StringProperties { get; }
}

and

public static class PropertyGrouper  {
    public static void GroupProperties(IGrouping itemToGroup) {
        //has this been done before, if yes, return
        if (itemToGroup.StringProperties.Count > 0 || itemToGroup.BoolProperties.Count > 0 || itemToGroup.LongProperties.Count > 0 ) {
            return;
        }
        //otherwise
        if (itemToGroup.boolProp != null) {
            foreach (var bProp in itemToGroup.boolProp) {
                var succeeded = bool.TryParse(bProp.Value, out var bValue);
                itemToGroup.BoolProperties.Add(bProp.name, succeeded ? bValue : (bool?)null);
            }
        }
        if (itemToGroup.longProp != null) {
            foreach (var lProp in itemToGroup.longProp) {
                var succeeded = long.TryParse(lProp.Value, out var lValue);
                itemToGroup.LongProperties.Add(lProp.name, succeeded ? lValue : (long?)null);
            }
        }
        if (itemToGroup.stringProp != null) {
            foreach (var sProp in itemToGroup.stringProp) {
                itemToGroup.StringProperties.Add(sProp.name, sProp.Value);
            }
        }
    }
}

With those in place, I extended each of the XSD.exe-emitted classes. The TestPlan class was easy - I just added a typed property:

public partial class TestPlan {
    [XmlIgnore]
    public hashTree HashTree => Items[0] as hashTree;
}

The hashTreeThreadGroup and hashTreeHTTPSamplerProxy classes were extended in the same way (remember, I didn't name any of these classes, XSD.exe named them from your XML) . Each was declared to implement the IGrouping interface, and each got 3 dictionaries of properties (as required by IGrouping ). The three arrays in the IGrouping interface were in the XSD-emitted code:

public partial class hashTreeThreadGroup : IGrouping {
    [XmlIgnore]
    public Dictionary<string, bool?> BoolProperties { get; } = new Dictionary<string, bool?>();
    [XmlIgnore]
    public Dictionary<string, long?> LongProperties { get; } = new Dictionary<string, long?>();
    [XmlIgnore]
    public Dictionary<string, string> StringProperties { get; } = new Dictionary<string, string>();
}

public partial class hashTreeHTTPSamplerProxy : IGrouping {
    [XmlIgnore]
    public Dictionary<string, bool?> BoolProperties { get; } = new Dictionary<string, bool?>();
    [XmlIgnore]
    public Dictionary<string, long?> LongProperties { get; } = new Dictionary<string, long?>();
    [XmlIgnore]
    public Dictionary<string, string> StringProperties { get; } = new Dictionary<string, string>();
}

Finally, I extended hashTree class. I added three typed properties, each with a null check to make things clean. The ThreadGroupItem and HttpSamplerProxyItem properties each get a call to PropertyGrouper.GroupProperties . The first time this is called, the properties in the XmlSerializer-created property arrays are copied into Dictionaries.

public partial class hashTree {
    [XmlIgnore]
    public hashTree HashTree {
        get {
            if (hashTree1 != null) {
                return hashTree1[0] as hashTree;
            } else {
                return null;
            }
        }
    }


    [XmlIgnore]
    public hashTreeThreadGroup ThreadGroupItem {
        get {
            if (ThreadGroup != null) {
                var threadGroup = ThreadGroup[0]; // as hashTreeThreadGroup;
                PropertyGrouper.GroupProperties(threadGroup);
                return threadGroup;
            } else {
                return null;
            }
        }
    }

    [XmlIgnore]
    public hashTreeHTTPSamplerProxy HttpSamplerProxyItem {
        get {
            if (HTTPSamplerProxy != null) {
                var httpSamplerProxy = HTTPSamplerProxy[0];
                PropertyGrouper.GroupProperties(httpSamplerProxy);
                return httpSamplerProxy;
            } else {
                return null;
            }
        }
    }
}

With that all in place, I ran the same code.

   TestPlan result;
   using (var stream = new FileStream("source.xml", FileMode.Open, FileAccess.Read)) {
       var serializer = new XmlSerializer(typeof(TestPlan));
       result = (TestPlan)serializer.Deserialize(stream);
   }

This code is how I accessed your data with my first example.

 var numThreadsParsed = long.TryParse((((XmlSerializeForm.hashTree)result.Items[0]).hashTree1[0].ThreadGroup[0].stringProp[1].Value), out var numThreads);
 var httpSamplerPath = ((XmlSerializeForm.hashTree)result.Items[0]).hashTree1[0].hashTree1[0].hashTree1[0].HTTPSamplerProxy[0].stringProp[4].Value;

But, with the few simple additions I made (well, the code isn't that complicated, but getting it right was), accessing the properties is much cleaner:

 string numThreadsParsed = result.HashTree.HashTree.ThreadGroupItem.StringProperties["ThreadGroup.num_threads"];
 long? startTime = result.HashTree.HashTree.ThreadGroupItem.LongProperties["ThreadGroup.start_time"];
 string httpSamplerPath = result.HashTree.HashTree.HashTree.HashTree.HttpSamplerProxyItem.StringProperties["HTTPSampler.path"];
 bool? useKeepAlive = result.HashTree.HashTree.HashTree.HashTree.HttpSamplerProxyItem.BoolProperties["HTTPSampler.use_keepalive"];

There you go!

Use xml linq :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlData data = new XmlData(FILENAME);
        }
    }
    public class XmlData
    {
        public int? num_threads { get; set;}
        public int? ramp_time { get;set;}
        List<SamplerProxy> HTTPSamplerProxies { get;set;}

        public XmlData(string filename)
        {
            XDocument doc = XDocument.Load(filename);

            XElement threadGroup = doc.Descendants("ThreadGroup").FirstOrDefault();
            num_threads = (int?)threadGroup.Elements("stringProp").Where(x => (string)x.Attribute("name") == "ThreadGroup.num_threads").FirstOrDefault();
            ramp_time = (int?)threadGroup.Elements("stringProp").Where(x => (string)x.Attribute("name") == "ThreadGroup.ramp_time").FirstOrDefault();

            HTTPSamplerProxies = doc.Descendants("HTTPSamplerProxy").Select(x => new SamplerProxy() {
                path = (string)x.Elements("stringProp").Where(y => (string)y.Attribute("name") == "HTTPSampler.path").FirstOrDefault(),
                domain = (string)x.Elements("stringProp").Where(y => (string)y.Attribute("name") == "HTTPSampler.domain").FirstOrDefault()
            }).ToList();

        }
    }
    public class SamplerProxy
    {
        public string path { get; set; }
        public string domain { get; set; }
    }
}

With external lib Cinchoo ETL - an open source library, you can grab the chosen node values easily as below

Define .NET type

public class TestPlan
{
    [ChoXmlNodeRecordField(XPath = @"/ThreadGroup/stringProp[@name=""ThreadGroup.on_sample_error""]")]
    public string NumThreads { get; set; }
    [ChoXmlNodeRecordField(XPath = @"/ThreadGroup/stringProp[@name=""ThreadGroup.ramp_time""]")]
    public int RampTime { get; set; }

    [ChoXmlNodeRecordField(XPath = @"/hashTree/hashTree/HTTPSamplerProxy/stringProp[@name=""HTTPSampler.path""]")]
    public string Path { get; set; }
    [ChoXmlNodeRecordField(XPath = @"/hashTree/hashTree/HTTPSamplerProxy/stringProp[@name=""HTTPSampler.domain""]")]
    public string Domain { get; set; }
}

Then deserialize the input xml using Cinchoo ETL as below

static void Main()
{
    using (var p = new ChoXmlReader<TestPlan>("*** XML file path ***")
        .WithXPath("/TestPlan/hashTree/hashTree")
        )
    {
        foreach (var rec in p)
            Console.WriteLine(rec.Dump());
    }
}

Output:

-- ChoXmlReaderTest.Program+TestPlan State --
        NumThreads: continue
        RampTime: 1
        Path: /v1/test/test?debug=false
        Domain: www.abc.com/abc-service-api

Hope it helps.

Disclaimer: I'm the author of this library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM