C#解析名称为a的xml Attriubte,并将其写为名称b

时间:2011-02-25 09:07:18

标签: c# xml-serialization

我有一个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; }

2 个答案:

答案 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序列化属性应用于序列化程序。

See the MSDN Article

以下是使用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");
    }

您可以使用替代进行序列化或反序列化。