COBOL генерирует XML -файл с CDATA - PullRequest
3 голосов
/ 26 февраля 2020

Я пытаюсь создать файл XML на языке COBOL, используя оператор GENERATE. Все идет нормально. Но с этим конкретным xml он должен содержать внутри отдельный файл xml. Поэтому я хочу использовать тег CDATA вокруг него. Но есть ли способ сделать это в COBOL с помощью оператора GENERATE?

Вот пример.

   01    request.
         06    route.
         11    name                  PIC  X(030).
         11    version               PIC  9(004).
         06    question.
         11    IDENT                 PIC  9(009).
         11    xmlFileName           PIC  X(006).
         11    xmlFileInh            PIC  X(5000).

xmlFileInh должен быть заполнен другим XML файлом. Это может быть только xml или soap запрос.

Что-то вроде этого:

<?xml version="1.0" encoding="UTF-8"?>
<request>
  <route>
    <name>serviceRequest</name>
    <version>1</version>
  </route>
  <question>
    <IDENT>111111111</IDENT>
    <xmlFileName>FILE-1</xmlFileName>
    <xmlFileInh>
       <![CDATA[<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope.....<SOAP-ENV:Envelope]]>
    </xmlFileInh>
  </question>
</request>

Я пытался натянуть "<![CDATA[" and "]]>" вокруг входящего XML -файла а затем поместите его в xmlFileInh. Это что-то делает, но переводит все HTML управляющих символов в то, что мне не нужно в моем xml -файле. Оператор GENERATE ничего не делает с CDATA.

< becomes   &lt;
> becomes   &gt;
" becomes   &quot;
' becomes   &apos;
& becomes   &amp;

Я также попытался дать xmlFileInh другое изображение, даже типа XML. Это дает много новых видов тегов в моих XML, длина имени и длина данных и т. Д. c. но я не хочу.

У кого-нибудь есть решение?

Заранее спасибо, Мартин.

Ответы [ 3 ]

2 голосов
/ 26 февраля 2020

Возможно, вам вообще не нужно использовать CDATA. XML GENERATE возьмет содержимое XMLFILEINH и экранирует специальные символы (как вы указали). Результирующий XML при просмотре в простом текстовом редакторе покажет escape-последовательности - не то, что вы хотите. Однако, когда вы используете XML PARSE для его обработки, экранированные символы снова будут заменены их исходным содержимым. Кроме того, большинство XML осведомленных читателей (например, Microsoft Edge среди прочих) будут отображать контент, как вы ожидаете, без escape-последовательностей.

Вот пример программы IBM Enterprise COBOL 6.2, иллюстрирующий мою точку зрения:

  IDENTIFICATION DIVISION.
  PROGRAM-ID. XML5.
  DATA DIVISION.
  WORKING-STORAGE SECTION.

  01  REQUEST.
      06 ROUTE.
        11 NAME                  PIC  X(030).
        11 VERSION               PIC  9(004).
      06 QUESTION.
        11 IDENT                 PIC  9(009).
        11 XMLFILENAME           PIC  X(006).
        11 XMLFILEINH            PIC  X(5000).


  01  XML-DOC                    PIC X(5000).
  01  XML-IDX                    PIC S9(9) BINARY.
  01  XML-CHAR-CNT               PIC S9(9) BINARY.

  PROCEDURE DIVISION.
  MAINLINE SECTION.
      MOVE 'serviceRequest' TO NAME
      MOVE 1                TO VERSION
      MOVE 111111111        TO IDENT
      MOVE 'FILE-1'         TO XMLFILENAME
      MOVE '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelop
 -         'e.....<SOAP-ENV:Envelope>'
        TO XMLFILEINH

      INITIALIZE XML-DOC
      XML GENERATE XML-DOC FROM REQUEST COUNT IN XML-CHAR-CNT
      PERFORM VARYING XML-IDX FROM 1 BY 80
                UNTIL XML-IDX > XML-CHAR-CNT
         DISPLAY XML-DOC (XML-IDX : 80)
      END-PERFORM

      XML PARSE XML-DOC PROCESSING PROCEDURE XML-HANDLER
          ON EXCEPTION
             DISPLAY 'XML Error: ' XML-CODE
             GOBACK
          NOT ON EXCEPTION
             DISPLAY 'ALL DONE.'
      END-XML
      GOBACK
      .

  XML-HANDLER.
      DISPLAY XML-EVENT (1:22) ':' XML-TEXT
      .

Вывод:

<REQUEST><ROUTE><NAME>serviceRequest</NAME><VERSION>1</VERSION></ROUTE><QUESTION
><IDENT>111111111</IDENT><_XMLFILENAME>FILE-1</_XMLFILENAME><_XMLFILEINH>&lt;?xm
l version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;SOAP-ENV:Envelope..
...&lt;SOAP-ENV:Envelope&gt;</_XMLFILEINH></QUESTION></REQUEST>
START-OF-DOCUMENT     :
START-OF-ELEMENT      :REQUEST
START-OF-ELEMENT      :ROUTE
START-OF-ELEMENT      :NAME
CONTENT-CHARACTERS    :serviceRequest
END-OF-ELEMENT        :NAME
START-OF-ELEMENT      :VERSION
CONTENT-CHARACTERS    :1
END-OF-ELEMENT        :VERSION
END-OF-ELEMENT        :ROUTE
START-OF-ELEMENT      :QUESTION
START-OF-ELEMENT      :IDENT
CONTENT-CHARACTERS    :111111111
END-OF-ELEMENT        :IDENT
START-OF-ELEMENT      :_XMLFILENAME
CONTENT-CHARACTERS    :FILE-1
END-OF-ELEMENT        :_XMLFILENAME
START-OF-ELEMENT      :_XMLFILEINH
CONTENT-CHARACTERS    :<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope.....<SOAP-ENV:Envelope>
END-OF-ELEMENT        :_XMLFILEINH
END-OF-ELEMENT        :QUESTION
END-OF-ELEMENT        :REQUEST
END-OF-DOCUMENT       :
ALL DONE.

Обратите внимание на экранирование специальных символов в «сыром» дампе сгенерированного XML, но после завершения XML PARSE они восстанавливаются до того, что было дано до XML ГЕНЕРАЦИЯ. Это нормальная XML обработка. Такие экранирующие символы могут защитить вас от преобразования кодовых страниц при передаче сгенерированного XML. При использовании CDATA существует вероятность повреждения, когда документ необходимо преобразовать из одной кодовой страницы в другую, и нет прямого сопоставления для данного символа (маловероятно, но возможно).

Что мне здесь интересно и не может объяснить, почему сгенерированные XML имена тегов, начинающиеся с XML, имеют префикс подчеркивания.

Последнее примечание: Если содержимое переменной COBOL XMLFILEINH содержало последовательность </_XMLFILEINH> где-то можно подумать, что это приведет к преждевременному окончанию тега <_XMLFILEINH> в результирующем XML. Это не потому, что открывающие и закрывающие разделители < и > экранируются в GENERATE.

1 голос
/ 26 февраля 2020

Корпоративный COBOL IBM в настоящее время не имеет опций для генерации CDATA.

Чтобы решить вашу проблему, вы можете оставить xmlFileInh без заполнения, XML GENERATE в SOME-BUFFER, а затем ...

UNSTRING 
  SOME-BUFFER 
  DELIMITED '<xmlFileInh>' OR '</xmlFileInh>' 
  INTO 
    FIRST-PART  COUNT IN FIRST-PART-COUNT
      DELIMITER IN FIRST-DELIMITER 
    SECOND-PART
      DELIMITER IN SECOND-DELIMITER 
    THIRD-PART  COUNT IN THIRD-PART-COUNT
END-UNSTRING

... тогда ...

STRING 
    FIRST-PART(1:FIRST-PART-COUNT)   DELIMITED SIZE
    FIRST-DELIMITER                  DELIMITED SPACE
    CDATA-CONTENT                    DELIMITED ']]>'
    ']]>'                            DELIMITED SIZE
    SECOND-DELIMITER                 DELIMITED SPACE
    THIRD-PART(1:THIRD-PART-COUNT)   DELIMITED SIZE
  INTO FINAL-DESTINATION
END-STRING

... которую я только что получил от руки, так что никаких гарантий. Это также эстетически неприятно, и кто-то должен отправить RFE в IBM для обработки CDATA в XML GENERATE.

0 голосов
/ 28 февраля 2020

Прочитав ответ @FredTheFlinstone, я понял, что это именно то, что нужно моей ситуации. XML, сгенерированный со встроенным xml внутри, PARSEd другой программой на языке COBOL. Поэтому я использовал решение, не добавляя CDATA перед концом в конце встроенного XML.

. Здесь есть некоторые дополнительные вещи, которые следует учитывать (в моем случае):

The XML для помещения в XMLFILEINH исходит от MQ в UTF-8. Переменные в REQUEST находятся в рабочем хранилище, поэтому EBCDI C. GENERATE нужно сделать REQUEST- xml в UTF-8, поэтому я добавил ENCODING 1208. GENERATE нужны все поля в EBCDI C, поэтому мне сначала нужно перевести ввод с помощью функций DISPLAY-OF и NATIONAL-OF.

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

Последнее, о подчеркиваниях в тэгах, начинающихся с XML. Я понятия не имею. Я думаю, это из-за названия 'XML'? Это была пробная просьба прояснить мой вопрос здесь. Я использую другие слова для генерации моего запроса, а не XML. Подчеркивания отсутствуют.

Если бы мой запрос должен был go вне среды COBOL мэйнфрейма, то мне, возможно, пришлось бы использовать другой параметр, указанный здесь @cschneid. Я также передам сообщение нашим техническим специалистам, которые имеют дело с IBM.

Несмотря на то, что, возможно, поскольку символы excape кажутся стандартными xml, другие парсеры на других платформах работают с ним так же. Но это оставляет вопрос, зачем вообще использовать CDATA .... Это должно быть полезно для чего-то.

В любом случае, спасибо за ответы! Это решило мою проблему.

...