反序列化特定的XML字符串

时间:2011-01-23 09:49:49

标签: c# xml web-services soap

我有一个问题,我无法摆脱它。我对WebServices的了解不是很好,我有一点需要解决的问题。 我正在为Web服务开发一个客户端,我对服务器端Web服务没有任何影响(我认为它是用Java开发的)。我使用WSE3来建立我的客户端,它似乎工作得很好,除了几种方法,我无法解决。 基于我的WSDL定义,我生成了我的代理类,使用适当的数据类型和方法来调用。其中许多方法返回已经反序列化的SOAP消息,并转换为正确的对象类型。不幸的是,他们中的一些人发送了一个ZIP文件的字节数组,其中包含一个格式不正确的xml文件。我设法获取流,解压缩文件并读取xml,但我无法正确反序列化xml,然后将其转换为相应的类型。这是我的代码示例,以及我需要反序列化并转换为正确类型的xml示例。你有什么建议吗?

MyClient client = new MyClient(ServiceSettings);
ConnectResponseRetrieveMyType data;

try
{
    // call web service method
    data = client.syncData(service, startDate, endDate);

    // unzip the byte array
    using (ZipFile zip = ZipFile.Read(data.Data))
    {
        if (zip.ContainsEntry("data.xml"))
        {
            List<string> strings = new List<string>();

            // read the xml file with multiple root elements
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;

            using (XmlReader reader = XmlReader.Create(zip["data.xml"].OpenReader(), settings))
            {
                while (reader.Read())
                {   
                    strings.Add(reader.ReadOuterXml());
                }
            }

        }
        else
            return "OGZIP01";
    }
}

最后我有一个List&lt;&gt;包含此数据的字符串:

<c:CoverDecision TypeOfCover="CreditLimit" CoverId="123123123" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:c="http://atradius.com/connect/_2007_08/" xmlns:o="http://atradius.com/organisation/_2007_08/type/">
    <Buyer>
        <o:Identifier registeredOffice="SYMPH">
            <o:id>123123123</o:id>
            <o:countryTypeIdentifier>AUT</o:countryTypeIdentifier>
        </o:Identifier>
        <o:Identifier registeredOffice="COC">
            <o:id>123123123F</o:id>
            <o:countryTypeIdentifier>AUT</o:countryTypeIdentifier>
        </o:Identifier>
        <o:Name>
            <o:name>SOME GES.M.B.H.</o:name>
            <o:type>REG</o:type>
        </o:Name>
        <o:LegalForm>GMBH</o:LegalForm>
        <o:Address>
            <o:StreetDescription xsi:type="xsd:string">STRAßE 49</o:StreetDescription>
            <o:City>FÜRSTENFELD</o:City>
            <o:PostCode>23123</o:PostCode>
            <o:CountryISOCode>AUT</o:CountryISOCode>
        </o:Address>
    </Buyer>
    <Customer>
        <o:Identifier registeredOffice="SYMPH">
            <o:id>123123</o:id>
            <o:countryTypeIdentifier>NLD</o:countryTypeIdentifier>
        </o:Identifier>
        <o:Identifier registeredOffice="COC">
            <o:id>123123</o:id>
            <o:countryTypeIdentifier>NLD</o:countryTypeIdentifier>
        </o:Identifier>
        <o:Name>
            <o:name>SOME B.V.</o:name>
            <o:type>REG</o:type>
        </o:Name>
    </Customer>
    <PolicyId>123123</PolicyId>
    <GenericApplication>
        <CustomerReference>123123</CustomerReference>
        <EntryDate>2010-02-04</EntryDate>
        <Supersede>false</Supersede>
    </GenericApplication>
    <Decision>
        <ApplicationResult>CreditLimitDecision</ApplicationResult>
        <DecisionDate>2010-02-05</DecisionDate>
        <EffectFrom>2010-02-05</EffectFrom>
        <EffectTo>2010-07-19</EffectTo>
        <CreditLimitDecision>
            <CreditLimitResultCode>APPR</CreditLimitResultCode>
            <DecisionCode>DC16</DecisionCode>
            <FirstAmount>
                <Amount>150000.00</Amount>
                <Conditions>
                    <TypeOfConditions>ADMIN</TypeOfConditions>
                    <ConditionCode>T310</ConditionCode>
                    <ConditionText>Some condition description text.</ConditionText>
                </Conditions>
            </FirstAmount>
            <SecondAmount>
                <Amount>0</Amount>
            </SecondAmount>
        </CreditLimitDecision>
    </Decision>
</c:CoverDecision>

我无法将其反序列化并将其转换为正确的对象类型。我尝试了很多方法,但我没有成功。也许你有什么建议吗?

谢谢

3 个答案:

答案 0 :(得分:1)

是的,xml未格式化。 每个'identifier'元素都应该在'identifier'中。

除此之外,其他类型非常简单(对于标识符,在买方和消费者类型中创建List<Identifier>

阅读数据的最简单方法是使用DataSet.ReadXml(xmlfile); 加载数据后,您将拥有“CoverDecision”,“买方”,“标识符”等表格。它也会创建关系(dataSet.Relations),在你的情况下是13个。

因此,在关系的帮助下导航表格,您可以获得所有数据。

答案 1 :(得分:1)

回应Vijay Sirigiri。

感谢重播。我已经尝试过这个解决方案并且工作正常:

using (XmlReader reader = XmlReader.Create(zip["data.xml"].OpenReader(), settings))
{
 while (reader.Read())
 {
    ds.ReadXml(reader);
  ...

它就像你伤心一样有效。如果我找不到另一个,这可能是一个反弹的解决方案。

奇怪的是,如果我回想起WS中的方法应该给我一个CoverDecision,我会找回正确的对象,反序列化并转换。我很遗憾,是否有可能复制WSE3用于反序列化该对象的相同行为? 例如,这工作正常,我记得WS方法,我得到了包含以下内容的ConnectResponseType(SOAPResponse):

CoverDecisionType response = SOAPResponse.CoverDecision;

了解如何做到这一点?

答案 2 :(得分:1)

得到了答案。坦克扬! 显然,XmlSerializer不知道如何处理名称空间和根元素。

此属性有助于解决问题。

[System.Xml.Serialization.XmlRootAttribute("CoverDecision", Namespace = "http://atradius.com/connect/_2007_08/", IsNullable = false)]
public partial class CoverDecisionType

感谢所有帮助我集思广益的人!