我有这个类来反序列化我的类:
public class Serializer <T> {
public T SerializeAppPath(string xmlpath) {
T apppath;
using (TextReader txtReader = new StreamReader(xmlpath)) {
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
apppath = (T)xmlSerializer.Deserialize(txtReader);
return apppath;
}
}
}
这是我想要将XML反序列化为的类:
[XmlRoot("KPIPATHS")]
public sealed class KpiPath
{
public sealed class KPI
{
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("RequestTemplateFullPath")]
public string RequestTemplateFullPath { get; set; }
[XmlElement("RequestFullPath")]
public string RequestFullPath { get; set; }
public KPI()
{
}
}
[XmlArray("KPIS")]
public List<KPI> Kpis { get; set; }
public KpiPath()
{
}
}
以下是我执行它以获取XML结果的方法。我正在检索&#34; Kpis&#34;我的问题是我想从它只取一个基于条件KPI
的{{1}}集合,然后我想使用并进一步传递"when Name = something"
类。希望你明白我的意思。
KpiPath
一些示例XML:
Serializer<KpiPath> serializer2 = new Serializer<KpiPath>();
kpiPath = serializer2.SerializeAppPath(KpiPaths);
答案 0 :(得分:0)
使用XmlSerializer
将始终反序列化/序列化给定类型的所有内容。您正试图有条件地查询不同功能的XML文档。 XmlSerialization不应该用作对XML的查询,而应该采用整个给定类型并将其完全序列化到 XML或从 XML反序列化给定类型的新实例。此外,在给定的序列化链中只能定义一个XmlRoot属性。
来自MSDN:
有两个属性可以应用于一个类(并且只有一个 class):XmlRootAttribute和XmlTypeAttribute。这些属性是 非常相似。 XmlRootAttribute只能应用于一个类: 序列化时表示XML文档的开头的类 和关闭元素 - 换句话说,根元素。该 另一方面,XmlTypeAttribute可以应用于任何类, 包括根类。
有关详细信息,请参阅此处:http://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.110).aspx
简而言之,您希望在序列化期间将不同的节点作为XML根目录,这是不受支持的。
在您的情况下,我会在KpiPath
类中添加一个函数,以便在类型实例完全解除分类后查询类型实例中的数据(因为函数和方法不可序列化),类似于:
void Main() {
XmlSerializer ser = new XmlSerializer(typeof(KpiPath));
KpiPath newPath = new KpiPath();
newPath.Kpis.Add(new KPI() {Name = "test", RequestTemplateFullPath = @"C:\test", RequestFullPath = @"C:\test"});
newPath.Kpis.Add(new KPI() {Name = "test", RequestTemplateFullPath = @"C:\newTest", RequestFullPath = @"C:\newTest"});
newPath.Kpis.Add(new KPI() {Name = "anotherTest", RequestTemplateFullPath = @"C:\funTest", RequestFullPath = @"C:\funTest"});
StringBuilder sb = new StringBuilder();
using(StringWriter writer = new StringWriter(sb)) {
ser.Serialize(writer, newPath);
} // end using
Debug.WriteLine(sb.ToString());
List<KPI> matches = newPath.KPIFromName("test");
//For debugging, make sure we get two results (matching the two named test above), print a failure message if not.
Debug.Assert(matches.Count == 2, "Invalid Count");
}
[XmlRoot("KPIPATHS"), Serializable()]
public sealed class KpiPath {
[XmlArray("KPIS")]
public List<KPI> Kpis { get; set; }
public KpiPath() {
Kpis = new List<KPI>();
} // end default constructor
public List<KPI> KPIFromName(string kpiName) {
if(String.IsNullOrWhiteSpace(kpiName)) {
throw new ArgumentNullException("kpiName", "No name provided.");
} // end if
List<KPI> matches = new List<KPI>();
if(this.Kpis.Any()) {
for(int i = 0; i < this.Kpis.Count; i++) {
if(this.Kpis[i].Name.ToUpperInvariant() == kpiName.ToUpperInvariant()) {
matches.Add(this.Kpis[i]);
} // end if
} // end for loop
} // end if
return matches;
} // end function GetFromName
} // end class KpiPath
[Serializable()]
public sealed class KPI {
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("RequestTemplateFullPath")]
public string RequestTemplateFullPath { get; set; }
[XmlElement("RequestFullPath")]
public string RequestFullPath { get; set; }
public KPI() {
} // end default constructor
} // end class KPI
通过这种方式,您可以轻松地检索具有您感兴趣的名称的项目,并且您不必具有任何复杂/难以遵循的反序列化逻辑。
如果这对您来说不是一个好的解决方案,我建议您使用XmlReader
/ XmlDocument
组合来阅读基于XPath的文档中的特定项目(XPath )语法。
以下是一些解决此问题的相关主题: