C #: Как проанализировать сообщение EDIFACT с помощью Xml Serializer - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть такое сообщение 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'

Это сообщение продолжается более 1 миллиона строк.

Я использовал 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 нет родителя.

Могу ли я решить эту проблему, улучшив свой код, или попробовать другим способом?

Если вам нужна дополнительная информация, пожалуйста, спросите меня?я дам вам более подробную информацию

ОБНОВЛЕНИЕ: Я решил эту проблему.

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Я бы хотел увидеть спецификацию формата ввода, а не просто пример , перед тем как приступить к выполнению этой задачи, особенно если количество преобразуемых данных слишком велико для проверьте правильность результата визуальным осмотром.

Я думаю, что вы находитесь на правильных строках, однако: сначала выполните грубый анализ входных данных, которые создают какое-то представление 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, с четкой взаимосвязью между ними.

0 голосов
/ 17 сентября 2018

Этот вопрос очень широкий. В основном вы должны понимать формат, а затем написать программное обеспечение для извлечения и преобразования его в нужный формат. К счастью, вы не первый, кто столкнулся с этой проблемой, и есть решения с открытым исходным кодом:

Есть ли в Java хороший парсер EDIFACT с открытым исходным кодом?

...