我有一个XML dom
<xml>
<ElementA/>
<xml>
现在我的xml已更改
<xml>
<ElementB/>
<xml>
ElementB和A的值是相似的,但我有几个带有ElementA的文件,必须将它们迁移到ElementB。
我正在使用XmlSerializer
是否可以将两个节点读取到一个参数并将它们写入一个属性名称,如
[XmlElement("ElementB")]
[XmlElement("ElementA")] // Writing this version only somehow
public float Rating
{ get; set; }
答案 0 :(得分:2)
我过去使用Linq to XML(System.Xml.Linq)来完成这种模式迁移工作并取得了巨大成功。您的代码看起来像:
XDocument doc = XDocument.Load("<path to input xml document>");
foreach (var element in doc.Descendants("AttributeA"))
{
element.Name = "AttributeB";
}
doc.Save("<path to output xml document>");
基本上,您只需将整个文档读入XDocument,通过Linq查找您要查找的节点,操作它们的值,然后将更改后的XDocument写回光盘。然后,如果您仍想使用Xml序列化,您将再次从光盘读取该文档并继续像以前一样处理。
答案 1 :(得分:1)
您可以使用XML Attribute Overrides执行所需操作。实质上 您可以在运行时将XML序列化属性应用于序列化程序。
以下是使用XML序列化的XML属性覆盖的一些示例代码。
public class DTO
{
[XmlIgnore]
public string additionalInformation;
[XmlElement(Order=1)]
public DateTime stamp;
[XmlElement(Order=2)]
public string name;
[XmlElement(Order=3)]
public double value;
[XmlElement(Order=4)]
public int index;
}
public class OverridesDemo
{
public void Run()
{
DTO dto = new DTO {
additionalInformation = "This information will be serialized separately",
stamp = DateTime.UtcNow,
name = "Marley",
value = 72.34,
index = 7
};
// this will allow us to omit the xmlns:xsi namespace
var ns = new XmlSerializerNamespaces();
ns.Add( "", "" );
XmlSerializer s1 = new XmlSerializer(typeof(DTO));
var builder = new System.Text.StringBuilder();
var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
Console.WriteLine("\nSerialize using the in-line (compile-time) attributes: ");
using ( XmlWriter writer = XmlWriter.Create(builder, settings))
{
s1.Serialize(writer, dto, ns);
}
Console.WriteLine("{0}",builder.ToString());
Console.WriteLine("\n");
// use a default namespace
ns = new XmlSerializerNamespaces();
string myns = "urn:www.example.org";
ns.Add( "", myns );
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attrs = new XmlAttributes();
// override the (implicit) XmlRoot attribute
XmlRootAttribute attr1 = new XmlRootAttribute
{
Namespace = myns,
ElementName = "DTO-Annotations",
};
attrs.XmlRoot = attr1;
overrides.Add(typeof(DTO), attrs);
// "un-ignore" the first property
// define an XmlElement attribute, for a type of "String", with no namespace
var a2 = new XmlElementAttribute(typeof(String)) { ElementName="note", Namespace = myns };
// add that XmlElement attribute to the 2nd bunch of attributes
attrs = new XmlAttributes();
attrs.XmlElements.Add(a2);
attrs.XmlIgnore = false;
// add that bunch of attributes to the container for the type, and
// specifically apply that bunch to the "Label" property on the type.
overrides.Add(typeof(DTO), "additionalInformation", attrs);
// ignore the other properties
// add the XmlIgnore attribute to the 2nd bunch of attributes
attrs = new XmlAttributes();
attrs.XmlIgnore = true;
// add that bunch of attributes to the container for the type, and
// specifically apply that bunch to the "Label" property on the type.
overrides.Add(typeof(DTO), "stamp", attrs);
overrides.Add(typeof(DTO), "name", attrs);
overrides.Add(typeof(DTO), "value", attrs);
overrides.Add(typeof(DTO), "index", attrs);
XmlSerializer s2 = new XmlSerializer(typeof(DTO), overrides);
Console.WriteLine("\nSerialize using the override attributes: ");
builder.Length = 0;
using ( XmlWriter writer = XmlWriter.Create(builder, settings))
{
s2.Serialize(writer, dto, ns);
}
Console.WriteLine("{0}",builder.ToString());
Console.WriteLine("\n");
}
您可以使用替代进行序列化或反序列化。