-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 行。

这是我想要的结构。

分支图

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

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

如果您需要更多详细信息,请问我?我会给你更多细节

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

4

2 回答 2

1

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

Java 中有没有好的开源 EDIFACT 解析器?

于 2018-09-17T10:21:36.420 回答
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 文档表示,两者之间有明确的关系。

于 2018-10-24T08:23:42.317 回答