Десериализация конкретной строки XML - PullRequest
4 голосов
/ 23 января 2011

У меня есть проблема, и я не могу ее решить.Мои знания о WebServices невелики, и у меня есть небольшая проблема, которую мне нужно решить.Я разрабатываю клиент для веб-сервиса, и у меня нет власти над серверным веб-сервисом (и я думаю, что он разработан на 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";
    }
}

В конце у меня есть список <> строки, содержащей эти данные:

<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 ]

1 голос
/ 23 января 2011

В ответ Виджай Сиригири.

Спасибо за повтор. Я уже пробовал это решение, и оно отлично работает:

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;

Поняли, как это сделать?

1 голос
/ 24 января 2011

Получил ответ. Танки Ян! По-видимому, XmlSerializer не знал, как обращаться с пространствами имен и корневым элементом.

Этот атрибут помогает решить проблему.

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

Так что спасибо всем, кто помог мне провести мозговой штурм!

1 голос
/ 23 января 2011

Да, верно, xml не отформатирован. Каждый элемент «идентификатора» должен быть внутри «идентификаторов».

Кроме того, с другими типами это довольно просто (для идентификатора создайте List<Identifier> в типах Покупатель и Потребитель.

Самый простой способ прочитать данные - это использовать DataSet.ReadXml(xmlfile); И как только данные будут загружены, у вас будет таблица для «CoverDecision», «Buyer», «Identifier» и так далее. Это также создаст отношения (dataSet.Relations), в вашем случае 13 из них.

Таким образом, перемещаясь по таблицам с помощью отношений, вы можете получить все данные.

...