将自动生成的类的实例序列化为XML字符串

时间:2012-07-13 08:31:58

标签: c# xml serialization xml-serialization

我从xsd.exe生成了以下类。这就是为什么我不能在代码中添加[XML Attribute("...")]这样的东西。

public partial class MethodCheckType {

    private WebServiceType[] webServiceField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("WebService")]
    public WebServiceType[] WebService {
        get {
            return this.webServiceField;
        }
        set {
            this.webServiceField = value;
        }
    }
}

public partial class WebServiceType {

    private string uRLField;

    private string parameterField;

    private string returnValueField;

    private CredentialsType credentialsField;

    /// <remarks/>
    public string URL {
        get {
            return this.uRLField;
        }
        set {
            this.uRLField = value;
        }
    }

    /// <remarks/>
    public string Parameter {
        get {
            return this.parameterField;
        }
        set {
            this.parameterField = value;
        }
    }

    /// <remarks/>
    public string ReturnValue {
        get {
            return this.returnValueField;
        }
        set {
            this.returnValueField = value;
        }
    }

    /// <remarks/>
    public CredentialsType Credentials {
        get {
            return this.credentialsField;
        }
        set {
            this.credentialsField = value;
        }
    }
}

也许我必须更改我的XSD文件然后我必须再次在类代码中写这个。

为了更好地理解它:我想证明另一种方法(下面的方法“ReadXml”)工作正确。

/// <summary>
/// Reads an XML File in an array of WebServiceType objects.
/// </summary>
/// <param name="path">The filename to read.</param>
/// <returns>An array of WebServiceType Objects.</returns>
public static WebServiceType[] ReadXml(string path)
{
    // Is the path NOT a valic UNC path?
    if (!IsValidPath(path))
    {
        Console.Write(MethodCheck.Properties.Resources.ERR003);
        return null;
    }

    XmlSerializer serializer = new XmlSerializer(typeof(MethodCheckType));
    MethodCheckType output = null;
    StringReader reader = null;

    try
    {
        reader = new StringReader(path);
        output = (MethodCheckType)serializer.Deserialize(reader);
    }
    catch (Exception)
    {
        throw;
    }
    finally
    {
        reader.Dispose();
    }

    return output.WebService;
}

要检查ReadXml方法,我必须编写一个方法(用于unti测试),该方法将一个WebServiceType对象数组作为参数返回一个字符串。我不知道如何编写这个方法。下面是一个示例字符串:

Sample Xml Document

修改 这段文字似乎很难理解。我会尝试以更清晰的方式制定它: 我已经有了ReadXml方法。为了证明它是否正常,我编写了一种测试方法:

 /// <summary>
 ///A test for ReadXml
 ///</summary>
 [TestMethod()]
 public void ReadXmlTest2()
 {
     string path = @"C:\Users\pp-admin\Documents\Visual Studio 2010\Methodenpruefung der Webservices\Methodenpruefung\Methodenpruefung\BeispielXmlDatei.xml";
     string expected = testXMLFile;
     string  actual;
     WebServiceType[] xmlSerialized = WebserviceReader.ReadXml(path);
     // Deserialisieren des XML Objekts um einen String zu bekommen
     actual = WebServiceType.SerializeToXml(xmlSerialized);
     Assert.AreEqual(expected, actual);
     Assert.Inconclusive("Verify the correctness of this test method.");
 }

方法SerializeToXml必须获取一个WebServiceType对象数组,但它应该返回一个完整的XML字符串,如示例所示。

/// <summary>
/// This method deserializes an arrayof WebServiceType objects into a XML string.
/// </summary>
/// <param name="services">The WebServiceType object to deserialize.</param>
/// <returns>A XML string.</returns>
public static string SerializeToXml(WebServiceType[] services)
{
    XmlSerializer serializer = new XmlSerializer(typeof(MethodCheckType));
    MemoryStream ms = null;
    StreamReader reader = null;
    StringBuilder builder = new StringBuilder();

    try
    {
        ms = new MemoryStream();
        reader = new StreamReader(ms);
        Object t = (Object)serializer.Deserialize(reader);
    }
    finally
    {
        reader.Dispose();
        ms.Dispose();
    }
    return null;
}

对我来说,“序列化”和“反序列化”的含义可能会让人感到困惑,对不起。但我希望现在我的意思更清楚一点。

修改 首先感谢下面的答案。 SerializeToXml方法现在似乎可以正常工作。

还有另一个问题:使用以下代码我收到错误:

[XmlElement(ElementName = "MethodCheck")]
public partial class MethodCheckType { }

错误消息是:

  

属性'XmlElement'在此声明类型上无效。它仅对'property,indexer,field,param,return'声明有效。

我必须添加另一个使用声明吗?或者为什么这不起作用?

2 个答案:

答案 0 :(得分:1)

是的,您需要序列化(将对象转换为可存储的某些表示形式,如字符串),而不是 deserialise (将字符串或其他表示形式转换为记忆中的物体。)

answer to your other question已经为您提供了所需的大部分内容。

public static string SerializeToXml(WebServiceType[] webServices)
{
    // Make a MethodCheck object to hold the services.
    // This ensures that you get a top-level <MethodCheck> tag in the XML.
    MethodCheckType container = new MethodCheckType();
    container.WebService = webServices;

    using (var writer = new StringWriter())
    {
        var serializer = new XmlSerializer(typeof(MethodCheckType));
        // Note that you're serializing, not deserializing.
        serializer.Serialize(writer, container);
        writer.Flush();
        return writer.ToString();
    }
}

但是,这里有两件事需要注意:

  • 比较两个XML字符串可能无法提供您想要的结果。即使XML在技术上是相同的,即使无关紧要的空格中的最小差异也会导致字符串比较返回false。例如,即使XML具有相同的结构,这两个XML块也将无法进行字符串比较:
<a><b>Text</b></a>

<a>
    <b>Text</b>
</a>
  • 标签的名称可能不正确。 标记称为<MethodCheck><WebService>类型被称为MethodCheckTypeWebServiceType,它们没有[XmlElement]属性来为它们提供不同的序列化名称,我认为是你在答案开头提到的。由于xsd.exe会为您生成部分类,因此您可以创建另一个源文件扩展生成的类。例如:
[XmlElement(ElementName = "WebService")]
partial class WebServiceType
{
}

// And the same for MethodCheckType.

答案 1 :(得分:0)

序列化和反序列化在分布式体系结构中起着重要作用。为简单起见,您可以说序列化正在以一种可以存储或从一台机器传输到另一台机器的方式将对象传输到字符串,反之亦然,该过程是反序列化。