【问题标题】:COBOL generating XML-file with CDATACOBOL 使用 CDATA 生成 XML 文件
【发布时间】:2020-06-10 04:52:36
【问题描述】:

我正在尝试使用 GENERATE 语句在 COBOL 中创建一个 XML 文件。 到目前为止,一切都很好。 但是对于这个特定的 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>

我尝试在传入的 XML 文件周围串入"&lt;![CDATA[" and "]]&gt;",然后将其放入 xmlFileInh。这会做一些事情,但会将所有 HTML 控制字符呈现为我不想要的 xml 文件中的内容。 GENERATE 语句对 CDATA 没有任何作用。

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

我还尝试给 xmlFileInh 提供另一张图片,甚至键入 XML。这在我的 XML、名称长度和数据长度等中提供了许多新类型的标签,但我不想要。

有人有解决办法吗?

提前致谢 马丁。

【问题讨论】:

    标签: xml cobol cdata generate


    【解决方案1】:

    阅读@FredTheFlinstone 的答案后,我知道这正是我的情况所需要的。 使用内部嵌入的 xml 生成的 XML 正在被另一个 COBOL 程序解析。 所以我使用了这个解决方案,没有在嵌入式 XML 的末尾添加 CDATA。

    这里有一些额外的事情需要考虑(就我而言):

    要放入 XMLFILEINH 的 XML 来自 UTF-8 格式的 MQ。 REQUEST 中的变量位于工作存储中,因此为 EBCDIC。 GENERATE 需要在 UTF-8 中制作 REQUEST-xml,所以我添加了 ENCODING 1208。 GENERATE 需要 EBCDIC 中的所有字段,所以我首先必须使用函数 DISPLAY-OF 和 NATIONAL-OF 翻译输入。

    还要确保初始化 XMLFILEINH 中的尾随字符。 GENERATE 语句只删除空格。显而易见,但很高兴知道。

    最后,关于以 XML 开头的标记名中的下划线。我一点头绪都没有。我认为这是因为其中的名称“XML”? 这只是一个试用请求,以在此处澄清我的问题。我使用其他词来生成我的请求,而不是其中包含 XML。没有下划线。

    如果我的请求必须超出大型机 COBOL 环境,那么我可能不得不使用@cschneid 在此处提供的其他选项。我还将在这里向与 IBM 打交道的技术人员传达信息。

    尽管可能,因为 excape 字符似乎是标准的 xml 用法,其他平台上的其他解析器处理它的方式相同。但这留下了为什么要使用 CDATA 的问题......它必须对某些东西有用。

    无论如何,感谢您的回答!它解决了我的问题。

    【讨论】:

      【解决方案2】:

      您可能根本不需要使用 CDATA。 XML GENERATE 将获取 XMLFILEINH 的内容并转义特殊字符(如您所指出的)。当使用简单的文本编辑器查看生成的 XML 时,将显示转义序列 - 这不是您想要的。但是,当您使用 XML PARSE 对其进行处理时,转义字符将再次被其原始内容替换。此外,大多数支持 XML 的查看器(例如 Microsoft Edge 等)将按照您的预期显示内容,而无需转义序列。

      这是一个 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 GENERATE 的内容。这是正常的 XML 处理。在传输生成的 XML 时,诸如此类的字符转义可能会保护您免受代码页转换的影响。使用 CDATA 时,当文档必须从一个代码页转换到另一个代码页并且给定字符没有直接映射时,可能会出现损坏(不太可能,但可能)。

      我在这里发现有趣但无法解释的是为什么生成的以XML 开头的 XML 标记名称带有下划线前缀。

      最后说明:如果 COBOL 变量 XMLFILEINH 的内容在某个地方包含序列 &lt;/_XMLFILEINH&gt;,人们可能会认为这会导致生成的 XML 中的 &lt;_XMLFILEINH&gt; 标记过早结束。这不是因为开始和结束分隔符 &lt;&gt; 在 GENERATE 上被转义。

      【讨论】:

        【解决方案3】:

        IBM 的 Enterprise COBOL 目前没有任何选项来处理生成 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
        

        ...我只是随意写的,所以不能保证。这在美学上也令人不快,应该有人向 IBM 提交 RFE 以处理 XML GENERATE 中的 CDATA。

        【讨论】:

          猜你喜欢
          • 2013-01-22
          • 1970-01-01
          • 2011-09-25
          • 1970-01-01
          • 2021-03-21
          • 1970-01-01
          • 1970-01-01
          • 2022-07-01
          • 2011-03-09
          相关资源
          最近更新 更多