如何有效地将旧的XML对象转换为新更新的XML对象?

时间:2016-04-26 05:28:38

标签: c# xml io

我正在尝试建立一种可靠的方法来更新我的软件,确保每当我发布程序更新时我都可以顺利更新我的用户文件。该软件是用C#编写的。

说我有一个人物:

 - Name
 - DoB
 - Nationality

这是我的人类的第0.1版。在将来,为了举例,我向person对象引入了一些新字段(v0.2)。

 - Name
 - DoB
 - Nationality
 - Temperament <- NEW
 - Job <- NEW

显然我需要将旧对象更新为新对象。我目前正在做的是:

  1. 将0.1对象读入版本化类(如Person01.cs)。
  2. 使用旧对象具有的字段填充新对象。
  3. 使用默认值填充新对象的新字段。
  4. 写出文件。
  5. 这看起来非常低效。每次我做出任何改变都需要大量的自定义编码。必须有一个更好的方法来做到这一点,但由于这是我第一次真正使用XML,我不知道如何去做。您将提供的任何帮助将不胜感激。我已经搜索了这个问题的解决方案,但我只发现了无关的结果。

3 个答案:

答案 0 :(得分:1)

你可以缩短步骤1&amp; 2通过将旧xml反序列化为新对象,例如假设你有一个像v1的人:

[XmlRoot("Person")]
public class PersonV1
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

然后你将它升级为人v2,如:

[XmlRoot("Person")]
public class PersonV2
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }
    public DateTime BirthDate { get; set; }
}

现在,您可以使用您为人v1读取的数据填充人v2,如:

// read from person v1
var p1 = new PersonV1();
p1.FirstName = "Jeff";
p1.LastName = "Price";
var xmlSerializer = new XmlSerializer(typeof(PersonV1));
var stream = new MemoryStream();
xmlSerializer.Serialize(stream, p1);
var xmlStringP1 = Encoding.ASCII.GetString(stream.ToArray());

// populate to person v2
var deserializer = new XmlSerializer(typeof(PersonV2));
TextReader reader = new StringReader(xmlStringP1);
var p2 = (PersonV2)deserializer.Deserialize(reader);

// further, set defaults for person v2

您可以在此处探索更多xml序列化自定义:http://www.codeproject.com/Articles/483055/XML-Serialization-and-Deserialization-Part-1

答案 1 :(得分:1)

我们有一个Person对象:

public class Person
{
    public string Name { get; set; }
    public DateTime DoB { get; set; }
    public string Nationality { get; set; }
}

然后我们添加新属性。不需要有不同版本的课程!只需添加属性和默认构造函数,即在其中设置新属性值。反序列化将设置这些值,而不是丢失。

public class Person
{
    public Person()
    {
        // set default value
        Temperament = "hot";
        Job = "office slave";
    }

    public string Name { get; set; }
    public DateTime DoB { get; set; }
    public string Nationality { get; set; }

    public string Temperament { get; set; }
    public string Job { get; set; }
}

答案 2 :(得分:1)

一个很好的简单解决方案是使用XSL Transformation。您只需将转换应用于XML文件或带XML数据的字符串,然后添加新属性即可。如何在C#中执行此操作的示例可以找到here

示例XML文件:

<?xml version="1.0" encoding="utf-8"?>
<person>
    <name>John</name>
    <DoB>2016-01-01</DoB>
</person>

示例XSL文件:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" encoding="UTF-8" indent="no"/>
    <xsl:template match="/">
        <person>
            <xsl:element name="name">
                <xsl:value-of select="/person/name"/>
            </xsl:element>
            <xsl:element name="DoB">
                <xsl:value-of select="/person/DoB"/>
            </xsl:element>
            <Temperament>Quick to anger</Temperament>
            <Job>Unemployed</Job>
        </person>
    </xsl:template>
</xsl:stylesheet>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<person>
    <name>John</name>
    <DoB>2016-01-01</DoB>
    <Temperament>Quick to anger</Temperament>
    <Job>Unemployed</Job>
</person>