C# 当自定义对象列表是泛型类型时,如何使用特定架构中另一个自定义对象的列表序列化自定义对象
我需要创建很多XML文件。它们非常相似,需要具有以下模式:C# 当自定义对象列表是泛型类型时,如何使用特定架构中另一个自定义对象的列表序列化自定义对象,c#,.net,xml,generics,serialization,C#,.net,Xml,Generics,Serialization,我需要创建很多XML文件。它们非常相似,需要具有以下模式: <Servidor> <VersaoLayout>0001</VersaoLayout> <!--Will not change--> <CodigoUJ>001001</CodigoUJ> <!--Will not change--> <ItemServidor> <!--
<Servidor>
<VersaoLayout>0001</VersaoLayout> <!--Will not change-->
<CodigoUJ>001001</CodigoUJ> <!--Will not change-->
<ItemServidor> <!--A list of <T> that will change-->
<CPFServidor>13579024681</CPFServidor>
<NomeServidor>Fulano Pereira Tal</NomeServidor>
</ItemServidor>
</Servidor>
<Servidor>
<VersaoLayout>versao01</VersaoLayout>
<CodigoUJ>999</CodigoUJ>
<ItensLayout>
<ServidorLayout>
<CPFServidor>4252813450</CPFServidor>
<NomeServidor>Antonio de Sousa Muniz</NomeServidor>
</ServidorLayout>
</ItensLayout>
</Serv>
0001
001001
13579024681
富拉诺佩雷拉酒店
请注意,对于我需要创建的所有文件,
和
标记都是相同的,
是不同的内容。所以我想:为什么不创建一个类并使用泛型来处理这种情况下的差异呢?目前我的课程如下:
//Kind of a container class that will hold the content that will vary.
[XmlRoot("Servidor", ElementName="Servidor")]
public class LayoutArquivoXML<T> where T : ItemLayout
{
[XmlElement("VersaoLayout")]
public string VersaoLayout { get; set; }
[XmlElement("CodigoUJ")]
public string CodigoUJ { get; set; }
//[XmlArrayItem("ItemServidor")]
public List<T> ItensLayout { get; set; }
// Constructors omited for simplicity
}
//A "ContentClass". I will have a bunch of classes similar to this
[XmlRoot("ItemServidor", ElementName = "ItemServidor")]
public class ServidorLayout : ItemLayout
{
[XmlElement("CPFServidor")]
public string CPFServidor { get; set; }
[XmlElement("NomeServidor")]
public string Nome { get; set; }
}
public string Serializador<T>(T objeto)
{
string xml = string.Empty;
using (var sw = new ISO8859StringWriter())
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); // to omit XML namespaces
var xs = new XmlSerializer(typeof(T));
xs.Serialize(sw, objeto, ns);
}
return xml;
}
//一种容器类,它将保存不同的内容。
[XmlRoot(“服务商”,ElementName=“服务商”)]
公共类LayoutArquivoXML,其中T:ItemLayout
{
[XmlElement(“VersaoLayout”)]
公共字符串VersaoLayout{get;set;}
[XmlElement(“CodigoUJ”)]
公共字符串CodigoUJ{get;set;}
//[XmlArrayItem(“ItemServidor”)]
公共列表ItensLayout{get;set;}
//为简单起见省略了构造函数
}
//“内容类”。我将有一系列类似的课程
[XmlRoot(“ItemServidor”,ElementName=“ItemServidor”)]
公共类服务布局:ItemLayout
{
[XmlElement(“CPFServidor”)]
公共字符串CPFServidor{get;set;}
[XmlElement(“NomeServidor”)]
公共字符串Nome{get;set;}
}
我以这种方式实例化我的“容器类”:
LayoutArquivoXML<ServidorLayout> layout = new Layout.LayoutArquivoXML<ServidorLayout>("versao01", "999", lstItensLayout.ToList());
LayoutArquivoXML布局=新布局.LayoutArquivoXML(“versao01”,“999”,lstItensLayout.ToList());
我的序列化方法如下所示:
//Kind of a container class that will hold the content that will vary.
[XmlRoot("Servidor", ElementName="Servidor")]
public class LayoutArquivoXML<T> where T : ItemLayout
{
[XmlElement("VersaoLayout")]
public string VersaoLayout { get; set; }
[XmlElement("CodigoUJ")]
public string CodigoUJ { get; set; }
//[XmlArrayItem("ItemServidor")]
public List<T> ItensLayout { get; set; }
// Constructors omited for simplicity
}
//A "ContentClass". I will have a bunch of classes similar to this
[XmlRoot("ItemServidor", ElementName = "ItemServidor")]
public class ServidorLayout : ItemLayout
{
[XmlElement("CPFServidor")]
public string CPFServidor { get; set; }
[XmlElement("NomeServidor")]
public string Nome { get; set; }
}
public string Serializador<T>(T objeto)
{
string xml = string.Empty;
using (var sw = new ISO8859StringWriter())
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); // to omit XML namespaces
var xs = new XmlSerializer(typeof(T));
xs.Serialize(sw, objeto, ns);
}
return xml;
}
公共字符串序列化程序(T对象)
{
stringxml=string.Empty;
使用(var sw=new ISO8859StringWriter())
{
XmlSerializerNamespaces ns=新的XmlSerializerNamespaces();
ns.Add(“,”);//省略XML名称空间
var xs=新的XmlSerializer(typeof(T));
序列化(sw、objeto、ns);
}
返回xml;
}
这些图形对象正在生成具有以下架构的XML:
<Servidor>
<VersaoLayout>0001</VersaoLayout> <!--Will not change-->
<CodigoUJ>001001</CodigoUJ> <!--Will not change-->
<ItemServidor> <!--A list of <T> that will change-->
<CPFServidor>13579024681</CPFServidor>
<NomeServidor>Fulano Pereira Tal</NomeServidor>
</ItemServidor>
</Servidor>
<Servidor>
<VersaoLayout>versao01</VersaoLayout>
<CodigoUJ>999</CodigoUJ>
<ItensLayout>
<ServidorLayout>
<CPFServidor>4252813450</CPFServidor>
<NomeServidor>Antonio de Sousa Muniz</NomeServidor>
</ServidorLayout>
</ItensLayout>
</Serv>
versao01
999
4252813450
安东尼奥·德索萨·穆尼兹
我不希望标记
在XML中。我需要做什么才能在所需的模式中生成XML
此外,根标记
需要根据我生成的文件进行更改,假设我需要创建另一个文件,其中根标记是另一个,假设:
LayoutArquivoXML<AnotherLayout> layout = new Layout.LayoutArquivoXML<AnotherLayout>("versao01", "999", anotherItensLayout.ToList());
LayoutArquivoXML布局=新布局.LayoutArquivoXML(“versao01”,“999”,anotherItensLayout.ToList());
有两个不同的问题
我不希望标记
在XML中。我需要做什么才能在所需的模式中生成XML
如将数组序列化为元素序列的for中所述,要将数组(列表、可枚举等)序列化为XML元素的平面序列,需要将XmlElement
属性应用于属性/字段
此外,根标记
需要根据我生成的文件进行更改
这由XmlRoot
属性控制
现在,如果您使用的是具体类,所有这些都适用。为了将它们动态应用于泛型类,可以使用类和接受此类参数的XmlSerializer
为此,首先向原始方法添加一个可选参数:
public string Serializador<T>(T objeto, XmlAttributeOverrides overrides = null)
{
string xml = string.Empty;
using (var sw = new ISO8859StringWriter())
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); // to omit XML namespaces
var xs = new XmlSerializer(typeof(T), overrides);
xs.Serialize(sw, objeto, ns);
xml = sw.ToString();
}
return xml;
}
public string Serializador(T objeto,XmlAttributeOverrides overrides overrides=null)
{
stringxml=string.Empty;
使用(var sw=new ISO8859StringWriter())
{
XmlSerializerNamespaces ns=新的XmlSerializerNamespaces();
ns.Add(“,”);//省略XML名称空间
var xs=新的XmlSerializer(typeof(T),重写);
序列化(sw、objeto、ns);
xml=sw.ToString();
}
返回xml;
}
然后创建如下所示的特定方法:
public string Serializador<T>(LayoutArquivoXML<T> objeto, string rootElementName, string contentElementName)
where T : ItemLayout
{
var xmlAttrOverrides = new XmlAttributeOverrides();
// Root element name override
var xmlRootAttrs = new XmlAttributes();
xmlRootAttrs.XmlRoot = new XmlRootAttribute(rootElementName);
xmlAttrOverrides.Add(typeof(LayoutArquivoXML<T>), xmlRootAttrs);
// Content element name override
var xmlContentAttrs = new XmlAttributes();
xmlContentAttrs.XmlElements.Add(new XmlElementAttribute(contentElementName));
xmlAttrOverrides.Add(typeof(LayoutArquivoXML<T>), "ItensLayout", xmlContentAttrs);
// Call the original method passing the overrides
return Serializador(objeto, xmlAttrOverrides);
}
var source = new LayoutArquivoXML<ServidorLayout>
{
VersaoLayout = "0001",
CodigoUJ = "001001",
ItensLayout = new List<ServidorLayout>
{
new ServidorLayout
{
CPFServidor = "13579024681",
Nome = "Fulano Pereira Tal",
},
}
};
var xml = Serializador(source, "Servidor", "ItemServidor");
publicstringserializador(LayoutArquivoXML对象、stringrootelementname、stringcontentelementname)
其中T:ItemLayout
{
var xmlAttrOverrides=新的XmlAttributeOverrides();
//根元素名称重写
var xmlRootAttrs=新的XmlAttributes();
xmlRootAttrs.XmlRoot=新的XmlRootAttribute(rootElementName);
Add(typeof(LayoutArquivoXML),xmlRootAttrs);
//内容元素名称覆盖
var xmlContentAttrs=新的XmlAttributes();
添加(新的XmlElementAttribute(contentElementName));
Add(typeof(LayoutArquivoXML),“ItensLayout”,xmlContentAttrs);
//调用传递重写的原始方法
返回Serializador(objeto、xmlAttrOverrides);
}
现在,您可以通过以下方式实现您的目标:
public string Serializador<T>(LayoutArquivoXML<T> objeto, string rootElementName, string contentElementName)
where T : ItemLayout
{
var xmlAttrOverrides = new XmlAttributeOverrides();
// Root element name override
var xmlRootAttrs = new XmlAttributes();
xmlRootAttrs.XmlRoot = new XmlRootAttribute(rootElementName);
xmlAttrOverrides.Add(typeof(LayoutArquivoXML<T>), xmlRootAttrs);
// Content element name override
var xmlContentAttrs = new XmlAttributes();
xmlContentAttrs.XmlElements.Add(new XmlElementAttribute(contentElementName));
xmlAttrOverrides.Add(typeof(LayoutArquivoXML<T>), "ItensLayout", xmlContentAttrs);
// Call the original method passing the overrides
return Serializador(objeto, xmlAttrOverrides);
}
var source = new LayoutArquivoXML<ServidorLayout>
{
VersaoLayout = "0001",
CodigoUJ = "001001",
ItensLayout = new List<ServidorLayout>
{
new ServidorLayout
{
CPFServidor = "13579024681",
Nome = "Fulano Pereira Tal",
},
}
};
var xml = Serializador(source, "Servidor", "ItemServidor");
var source=new LayoutArquivoXML
{
VersaoLayout=“0001”,
CodigoUJ=“001001”,
ItensLayout=新列表
{
新服务设施布局
{
CPFServidor=“13579024681”,
Nome=“Fulano Pereira Tal”,
},
}
};
var xml=Serializador(来源,“Servidor”、“ItemServidor”);
产生:
<Servidor>
<VersaoLayout>0001</VersaoLayout>
<CodigoUJ>001001</CodigoUJ>
<ItemServidor>
<CPFServidor>13579024681</CPFServidor>
<NomeServidor>Fulano Pereira Tal</NomeServidor>
</ItemServidor>
</Servidor>
0001
001001
13579024681
富拉诺佩雷拉酒店
您提出的是独立的问题。您的第一个问题,即如何使元素名称与泛型参数类型名称匹配,非常类似于。对于第二个问题,关于如何修改泛型的根名称,您将需要子类化LayoutArquivoXML。谢谢,它太完美了!