使用 SOAP 信封和无效的 xsd 地址反序列化 XML 文件

问题描述 投票:0回答:1

我想反序列化这种具有 SOAP 信封和标头中不再存在的无效 .xsd 地址的 XML 文件 (finvoiceack.xsd)。想要在我的 C# 代码中将节点获取到数据集或自己的变量中。但是我在 XML 文件中收到关于无效前缀或错误类型的错误消息。

这里是 XML 文件的示例:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" xmlns:spy="#this address doesn't work anymore#" xmlns:xlink="http://www.w3.org/1999/xlink">
<SOAP-ENV:Header>
<eb:MessageHeader xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:mustUnderstand="1" eb:id="20021209133003285" eb:version="2.0">
<eb:From>
<eb:PartyId>00370144030000</eb:PartyId>
<eb:Role>Sender</eb:Role>
</eb:From>
<eb:From>
<eb:PartyId>003703570000</eb:PartyId>
<eb:Role>Intermediator</eb:Role>
</eb:From>
<eb:To>
<eb:PartyId>003718960000</eb:PartyId>
<eb:Role>Receiver</eb:Role>
</eb:To>
<eb:To>
<eb:PartyId>NDEAXXXX</eb:PartyId>
<eb:Role>Intermediator</eb:Role>
</eb:To>
<eb:CPAId>yoursandmycpa</eb:CPAId>
<eb:ConversationId>Hercules</eb:ConversationId>
<eb:Service>Routing</eb:Service>
<eb:Action>ProcessInvoice</eb:Action>
<eb:MessageData>
<eb:MessageId>003703570000-NDEAXXXX-20230305020020000</eb:MessageId>
<eb:Timestamp>20230305020020000</eb:Timestamp>
<eb:RefToMessageId>19600-90e71000-ed2c-4990-894t-43f621923f00</eb:RefToMessageId>
</eb:MessageData>
</eb:MessageHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<eb:Manifest>
<eb:Reference eb:id="Finvoice" xlink:href="20020209-133103">
<eb:schema eb:location="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd"/>
</eb:Reference>
</eb:Manifest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<?xml version="1.0" encoding="ISO-8859-15"?>
<!DOCTYPE Finvoiceack SYSTEM "Finvoiceack.dtd">
<Finvoiceack xmlns="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd" xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" Version="1.0">
<Acknowledgement>
<eb:From>
<eb:PartyId>003718960000</eb:PartyId>
<eb:Role>Sender</eb:Role>
</eb:From>
<eb:From>
<eb:PartyId>NDEAXXXX</eb:PartyId>
<eb:Role>Intermediator</eb:Role>
</eb:From>
<eb:To>
<eb:PartyId>00370144030000</eb:PartyId>
<eb:Role>Receiver</eb:Role>
</eb:To>
<eb:To>
<eb:PartyId>003703570000</eb:PartyId>
<eb:Role>Intermediator</eb:Role>
</eb:To>
<MessageData>
<eb:MessageId>19600-90e71000-ed2c-4990-894t-43f621923f00</eb:MessageId>
<eb:Timestamp>2023-03-05T02:00:26+02</eb:Timestamp>
</MessageData>
<Reason>
<Code>2</Code>
<Text>No routing found for receiving party: 00370144030000</Text>
</Reason>
</Acknowledgement>
</Finvoiceack>

这是我的功能:

        private static void DeserializeXmlFileToList()
        {
            var xmlSerializer = new XmlSerializer(typeof(ACKFile));
       
            using(var reader = new StreamReader(@"C:\ACK\test1.xml")) 
            {
                var ACKFile = (List<ACKFile>)xmlSerializer.Deserialize(reader);
            }
        }

这是我的模型还没有准备好,但我认为如果我有有效的 XML 文件它应该可以工作:

    [Serializable]
    [XmlRoot(Namespace = "example.org/eb", ElementName = "Acknowledgement")]
    public class ACKFile
    {
        [XmlElement(Namespace = "example.org/eb", ElementName = "From")]
        public string From { get; set; }

        [XmlElement(Namespace = "example.org/eb", ElementName = "To")]
        public string To { get; set; }

        [XmlElement(ElementName = "MessageData")]
        public string MessageData { get; set; }

        [XmlElement(ElementName = "Reason")]
        public string Reason { get; set; }
    }
c# xml soap xml-parsing xml-serialization
1个回答
0
投票

剥离soap header后,可以反序列化为Finvoiceack模型。

我使用 Xml2CSharp 创建模型。我还必须将编码从 ISO-8859-15 更改为 ISO-8859-1 否则我会遇到异常:

System.InvalidOperationException: There is an error in XML document (1, 31).

 ---> System.Xml.XmlException: System does not support 'ISO-8859-15' encoding. Line 1, position 31.

 ---> System.ArgumentException: 'ISO-8859-15' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. (Parameter 'name')

我希望这能有所帮助(为可视化添加了 json 序列化):

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Xml;
using System.Xml.Serialization;
using Xml2CSharp;

var xml = """
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE Finvoiceack SYSTEM "Finvoiceack.dtd">
    <Finvoiceack xmlns="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd" xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" Version="1.0">
    <Acknowledgement>
    <eb:From>
    <eb:PartyId>003718960000</eb:PartyId>
    <eb:Role>Sender</eb:Role>
    </eb:From>
    <eb:From>
    <eb:PartyId>NDEAXXXX</eb:PartyId>
    <eb:Role>Intermediator</eb:Role>
    </eb:From>
    <eb:To>
    <eb:PartyId>00370144030000</eb:PartyId>
    <eb:Role>Receiver</eb:Role>
    </eb:To>
    <eb:To>
    <eb:PartyId>003703570000</eb:PartyId>
    <eb:Role>Intermediator</eb:Role>
    </eb:To>
    <MessageData>
    <eb:MessageId>19600-90e71000-ed2c-4990-894t-43f621923f00</eb:MessageId>
    <eb:Timestamp>2023-03-05T02:00:26+02</eb:Timestamp>
    </MessageData>
    <Reason>
    <Code>2</Code>
    <Text>No routing found for receiving party: 00370144030000</Text>
    </Reason>
    </Acknowledgement>
    </Finvoiceack>
    """;

DeserializeXmlFileToList(xml);

static void DeserializeXmlFileToList(string xml)
{
    var xmlSerializer = new XmlSerializer(typeof(Finvoiceack));

    var bytes = Encoding.UTF8.GetBytes(xml);
    var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
    using var stream = new MemoryStream(bytes);
    using var reader = XmlReader.Create(stream, settings);

    //using(var reader = new StreamReader(@"C:\ACK\test1.xml")) 
    
    var finvoiceack = (Finvoiceack)xmlSerializer.Deserialize(reader);
    var options = new JsonSerializerOptions { WriteIndented = true };
    var txt = JsonSerializer.Serialize(finvoiceack, options);
    Console.WriteLine(txt);
}

   /* 
    Licensed under the Apache License, Version 2.0
    
    http://www.apache.org/licenses/LICENSE-2.0
    */
namespace Xml2CSharp
{
    [XmlRoot(ElementName="From", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
    public class From {
        [XmlElement(ElementName="PartyId", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public string PartyId { get; set; }
        [XmlElement(ElementName="Role", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public string Role { get; set; }
    }

    [XmlRoot(ElementName="To", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
    public class To {
        [XmlElement(ElementName="PartyId", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public string PartyId { get; set; }
        [XmlElement(ElementName="Role", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public string Role { get; set; }
    }

    [XmlRoot(ElementName="MessageData", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
    public class MessageData {
        [XmlElement(ElementName="MessageId", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public string MessageId { get; set; }
        [XmlElement(ElementName="Timestamp", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public string Timestamp { get; set; }
    }

    [XmlRoot(ElementName="Reason", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
    public class Reason {
        [XmlElement(ElementName="Code", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
        public string Code { get; set; }
        [XmlElement(ElementName="Text", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
        public string Text { get; set; }
    }

    [XmlRoot(ElementName="Acknowledgement", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
    public class Acknowledgement {
        [XmlElement(ElementName="From", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public List<From> From { get; set; }
        [XmlElement(ElementName="To", Namespace="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd")]
        public List<To> To { get; set; }
        [XmlElement(ElementName="MessageData", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
        public MessageData MessageData { get; set; }
        [XmlElement(ElementName="Reason", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
        public Reason Reason { get; set; }
    }

    [XmlRoot(ElementName="Finvoiceack", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
    public class Finvoiceack {
        [XmlElement(ElementName="Acknowledgement", Namespace="http://www.pankkiyhdistys.fi/verkkolasku/finvoice/finvoiceack.xsd")]
        public Acknowledgement Acknowledgement { get; set; }
        [XmlAttribute(AttributeName="xmlns")]
        public string Xmlns { get; set; }
        [XmlAttribute(AttributeName="eb", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Eb { get; set; }
        [XmlAttribute(AttributeName="Version")]
        public string Version { get; set; }
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.