我需要创建大量的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>
请注意,标记<VersaoLayout>
和<CodigoUJ>
对于我需要创建的所有文件都是相同的,<ItemServidor>
是不同的内容。所以我想:为什么不创建一个类并使用泛型来处理这种情况的差异?目前我的课程如下:
//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; }
}
我正在实例化我的&#34;容器类&#34;这样:
LayoutArquivoXML<ServidorLayout> layout = new Layout.LayoutArquivoXML<ServidorLayout>("versao01", "999", lstItensLayout.ToList());
我的序列化方法如下:
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;
}
这些对象图正在生成具有以下模式的XML:
<Servidor>
<VersaoLayout>versao01</VersaoLayout>
<CodigoUJ>999</CodigoUJ>
<ItensLayout>
<ServidorLayout>
<CPFServidor>4252813450</CPFServidor>
<NomeServidor>Antonio de Sousa Muniz</NomeServidor>
</ServidorLayout>
</ItensLayout>
</Serv>
我不想在XML中使用标记<ItensLayout>
标记。我需要做什么才能在所需的模式中生成XML?
此外,根标记<Servidor>
将需要根据我生成的文件进行更改,想象我需要创建另一个文件,其中根标记为另一个,让我们说:
LayoutArquivoXML<AnotherLayout> layout = new Layout.LayoutArquivoXML<AnotherLayout>("versao01", "999", anotherItensLayout.ToList());
答案 0 :(得分:1)
有两个不同的问题。
我不希望XML中的标记
<ItensLayout>
标记。我需要做什么才能在所需的模式中生成XML?
如documentation中针对将数组序列化为元素序列所述,要将数组(列表,可枚举等)序列化为XML元素的平面序列,您需要将XmlElement
属性应用于属性/字段。
此外,根标记
<Servidor>
将需要根据我正在生成的文件进行更改
这由XmlRoot
属性控制。
现在,如果您使用的是具体类,则所有这些都适用。要将它们动态应用于您的通用类,您可以使用XmlOverrides
类和XmlSerializer
constructors接受此类参数。
为此,首先在原始方法中添加一个可选参数:
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>(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");
产生:
<Servidor>
<VersaoLayout>0001</VersaoLayout>
<CodigoUJ>001001</CodigoUJ>
<ItemServidor>
<CPFServidor>13579024681</CPFServidor>
<NomeServidor>Fulano Pereira Tal</NomeServidor>
</ItemServidor>
</Servidor>