Helenr
我已经更新了它以使其易于使用。我开始之前,我决定,你可能想的可能性longProps在HTTPSamplerProxy部分。它还使编码(很多)更容易和更清洁。我已经在没有任何 longProps 的情况下对其进行了测试,只是为了确保它以您期望的方式与现有 XML 一起工作。原流程对原始描述的更新以斜体显示我所做的是使用标准的 XSD.exe 工具获取您的源 XML 文件(在 HTTPSamplerProxy 部分中有一个额外的 longProp)并创建一个 XSD。然后我再次使用 XSD.exe 创建了一个(非常丑陋的)C# 文件。那时,整个混乱的根源是 TestPlan 类。这是 XSD.exe 生成的内容(更新 - 对新发出的 XSD.exe 代码的唯一更改是顶部的命名空间声明):/// <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; } }}其余的大部分是新的XSD.exe 发出的代码创建了一组部分类。我在一个单独的源文件中以几种方式扩展了部分类。但是,在开始之前,我声明了一个接口和一个静态工作类。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; }}和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); } } }}有了这些,我扩展了每个 XSD.exe 发出的类。这TestPlan门课很简单——我只是添加了一个类型化的属性:public partial class TestPlan { [XmlIgnore] public hashTree HashTree => Items[0] as hashTree;}在hashTreeThreadGroup与hashTreeHTTPSamplerProxy类相同的方式(请记住,我没有点名任何这些类的,XSD.EXE从XML命名他们)进行了扩展。每个都被声明为实现IGrouping接口,并且每个都有 3 个属性字典(根据 的要求IGrouping)。IGrouping接口中的三个数组位于XSD 发出的代码中: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>();}最后,我延长了hashTree课程。我添加了三个类型化的属性,每个都有一个空检查以使事情变得干净。ThreadGroupItem 和 HttpSamplerProxyItem 属性分别调用PropertyGrouper.GroupProperties. 第一次调用时,XmlSerializer 创建的属性数组中的属性被复制到字典中。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; } } }}一切就绪后,我运行了相同的代码。 TestPlan result; using (var stream = new FileStream("source.xml", FileMode.Open, FileAccess.Read)) { var serializer = new XmlSerializer(typeof(TestPlan)); result = (TestPlan)serializer.Deserialize(stream); }此代码是我使用第一个示例访问您的数据的方式。 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;但是,通过我做了一些简单的添加(好吧,代码并没有那么复杂,但是做对了),访问属性就更简洁了: 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"];给你!