C#:如何使用Xml Serializer解析EDIFACT消息

问题描述 投票:-4回答:2

我有这种EDIFACT消息。

UNB+IATB:1+NGI+OOS+180918:2003+Export_Dump++TR2+X'
UNH+1+IFLIRR:15:2:1A'
FDR+OM+135+160918'
FDD++INT'
REF'
STX+ACT'
IFD+++C+USD++N'
APD+:::::::ULN:SVO'
DAT+708:160918:0915+707:160918:1055'
STX+FD'
EQP+J+76W::EIFGN+OM'
EQI+++++++:::FGN'
EQD++++++A01'
SSQ+AVIH:5:5::::0:SSR'
SSQ+BIKE:5:5::::0:SSR'
SSQ+BSCT:2:2::::0:SSR+J'
SSQ+BSCT:5:3::::2:SSR+Y'
SSQ+INFT:15:10::::5:SSR'
SSQ+PETC:1:1::::0:SSR+J'
SSQ+PETC:3:3::::0:SSR+Y'
SSQ+POXY:1:1::::0:SSR'
SSQ+SPEQ:5:5::::0:SSR'
SSQ+STCR:0:0::::0:SSR+J'
SSQ+STCR:1:1::::0:SSR+Y'
SSQ+SVAN:1:1::::0:SSR+J'
SSQ+SVAN:3:3::::0:SSR+Y'
SSQ+TVLG:5:5::::0:SSR'
SSQ+TVSM:10:10::::0:SSR'
SSQ+UMNR:5:5::::0:SSR'
SSQ+WCOB:0:0::::0:SSR'
LEG+A01+NXC'
EQI+J:24:S+J:21:A+J:24:O+J:21:E'

此消息继续超过约100万行。

我使用了C#Xml Serializer并成功将此消息解析为XML文件。但结构不正确。

这是我的代码:

    switch (keyword)
                        {
                            case "UNB":

                                parts = specificLine.Split(new char[] { '+', ':' }, StringSplitOptions.RemoveEmptyEntries);
                                serialization = new XmlSerializer(typeof(UNB));
                                UNB HeaderText = new UNB(parts[1], parts[2], parts[3], parts[4], parts[5], parts[6]);
                                writer = XmlWriter.Create(TxtWriter, settings);
                                serialization.Serialize(writer, HeaderText, EmptyNS);
                                break;
                            case "UNH":
                                parts = specificLine.Split(new char[] { '+', ':' }, StringSplitOptions.RemoveEmptyEntries);
                                serialization = new XmlSerializer(typeof(UNH));
                                UNH BodyText = new UNH(parts[1],parts[2],parts[3],parts[4],parts[5]);
                                writer = XmlWriter.Create(TxtWriter, settings);
                                serialization.Serialize(writer, BodyText, EmptyNS);
                                break;
                            case "FDR":
                                flightDateInformation Gr0 = new flightDateInformation();
                                parts = specificLine.Split(new char[] { '+'}, StringSplitOptions.RemoveEmptyEntries);                        
                                serialization = new XmlSerializer(typeof(flightDateInformation));
                                flightDateDesignator fdrbody = new flightDateDesignator(parts[1], parts[2], parts[3]);
                                Gr0.flightDateDesignator = fdrbody;
                                writer = XmlWriter.Create(TxtWriter, settings);
                                serialization.Serialize(writer, Gr0, EmptyNS);
                                break;
} 

这是我的结构类代码示例:

    [XmlRoot(ElementName = "UNB", IsNullable = false), Serializable]
    public class UNB
    {
        [XmlAttribute]
        public string identifier;
        [XmlAttribute]
        public string version;
        [XmlAttribute]
        public string sender;
        [XmlAttribute]
        public string recipient;
        [XmlAttribute]
        public string dateofpreparation;
        [XmlAttribute]
        public string timeofpreparation;
        public UNB(string identifier, string version,string sender, string recipient, string dateofpreparation, string timeofpreparation)
        {
            this.identifier = identifier;
            this.version = version;
            this.sender = sender;
            this.recipient = recipient;
            this.dateofpreparation = dateofpreparation;
            this.timeofpreparation = timeofpreparation;
        }
        public UNB()
        {

        }
}

我的输出XML文件是这样的:

<UNB identifier="IATB" version="1" sender="NGI" recipient="OOS" dateofpreparation="180918" timeofpreparation="2003" /><UNH identifier="1" type="IFLIRR" version="15" release="2" agency="1A" /><flightDateInformation>
  <flightDateDesignator airlineCode="OM" flightNumber="135" departureDate="160918" />
</flightDateInformation><flightLevelInfo flightCharacteristics="INT" /><referenceInfomation /><flightFlags statusIndicator="ACT" /><inventoryParametersFD controlType="C" currencyCode="USD" isUnderActiveRevControl="N" /><additionalproductdetails>
  <departureLocation>ULN</departureLocation>
  <arrivalLocation>SVO</arrivalLocation>
</additionalproductdetails><scheduledTiming>
  <qualifier>708</qualifier>
  <date>160918</date>
  <time>0915</time>
</scheduledTiming><scheduledTiming>
  <qualifier>707</qualifier>
  <date>160918</date>
  <time>1055</time>
</scheduledTiming><dcsInformation statusIndicator="FD" /><aircraftInformation serviceType="J" aircraftType="76W">
  <eqtRegistrationNumber>EIFGN</eqtRegistrationNumber>
  <aircraftOwner>OM</aircraftOwner>
</aircraftInformation><acvInformation acvCode="FGN" /><saleableConfiguration configurationCode="A01" />
<newSSR quotaCounterName="AVIH">
  <maxQuantity>5</maxQuantity>
  <availability>5</availability>
  <counter>0</counter>
  <quotaType>SSR</quotaType>
</newSSR><newSSR quotaCounterName="BIKE">
  <maxQuantity>5</maxQuantity>
  <availability>5</availability>
  <counter>0</counter>
  <quotaType>SSR</quotaType>
</newSSR>
<newSSR quotaCounterName="BSCT" cabinCode="J">
  <maxQuantity>2</maxQuantity>
  <availability>2</availability>
  <counter>0</counter>
  <quotaType>SSR</quotaType>
</newSSR>

现在我的问题是:是的,我的代码已成功运行并解析成XML文件。但不是我想要的。每个节点只有1行。

这是我想要的结构。

Branching Digaram

每个节点都包含在其他父节点中。一些节点扩展到其他节点。我的输出XML没有任何父级。

我可以通过改进我的代码或尝试不同的方式来解决这个问题吗?

如果您有任何需要更多细节,请问我?我会告诉你更多细节

更新:我解决了这个问题。

c# xml serialization xml-serialization edifact
2个回答
1
投票

这个问题非常广泛。基本上你必须了解格式,然后编写一个软件来提取并将其转换为您想要的格式。幸运的是,您不是第一个遇到此问题的人,并且提供了openSource解决方案:

Is there any good open source EDIFACT parser in Java?


0
投票

在处理此任务之前,我希望看到输入格式的规范,而不仅仅是一个示例,特别是当要转换的数据量太大而无法通过目视检查来检查结果的正确性时。

但是,我认为你是在正确的方面:首先对输入进行粗略的解析,产生某种XML表示。然后使用XML工具(特别是XSLT)将这个原始XML转换为您真正想要的目标XML。

我无法从您的“实际输出”和“期望输出”图中看出详细的转换规则是什么,但它可能是某种分组转换,以从平面结构创建分层结构。这是XSLT中的常见任务,最好通过获取XSLT 2.0(或3.0)处理器并使用<xsl:for-each-group>指令来实现。例如,如果您的任务是将包装元素放在具有相同名称的相邻元素周围,则可以执行以下操作:

<xsl:for-each-group select="*" group-adjacent="name()">
  <xsl:choose>
    <xsl:when test="name()="SSR">
      <SSR-LIST><xsl:copy-of select="current-group()"/></SSR-LIST>
    </xsl:when>
    ....
    <xsl:otherwise>
      <xsl:copy-of select="current-group()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each-group>

如果你想对这个转换提出更具体的建议,我建议用一个具体的(和简短的!)输入和输出示例发布一个新问题,表示为XML文档,两者之间有明确的关系。

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