我正在尝试访问整个“< mynode>”下面的示例XML中的节点,包括开始和结束标记。我需要将XML片段作为XML存储在数据库中。
<a>
<mynode >
<c>Content</c>
<c>More content</c>
</mynode >
</a>
我可以访问XML PARSE函数,这就是我访问节点值的方式,但我不知道如何使用它来访问整个节点。
我想到的一个选项是记录元素开头和元素结尾XML-TEXT ='b'的文档位置,然后获取文档的那部分,但这看起来不够优雅。还有更好的方法吗?
编辑:我计算了我在文档中读取了多少个字符,并在到达“&lt; mynode&gt;”的开头和结尾时存储该值节点。
然后我可以使用
访问该文档STRING MY-DOCUMENT(MYNODE-START-POSE, (MYNODE-NODE-FINISH - MYNODE-NODE-START))
DELIMITED BY SIZE
INTO MY-AREA
答案 0 :(得分:3)
如果您使用IBM's Enterprise COBOL,则可以使用XML PARSE语句。解析器生成事件并填充special registers,govern execution of your code可供您使用XML GENERATE。 (由于某种原因,最后一个链接无法正常工作,它应该会带您进入该页面上的“控制流”标记)
如果需要“修剪”树结构的某些部分(包括标记和数据),则可能需要解析原始数据,填充结构,并使用{{3}}获取所需的XML数据流。看起来解析器不会告诉您原始XML数据流中每个事件发生的位置,至少似乎没有一个特殊的寄存器可以填充该值。
答案 1 :(得分:2)
COBOL XML PARSE不提供位置信息(AFAIK)。确定偏移位置在哪里 发生给定事件是不可能的。感兴趣的标签的文本搜索 必然会导致大量问题 - 甚至不想去那里......
我能想到的下一个可能性是在解析时构造感兴趣的XML片段文档 原始文件。片段完成后,将其写入XML数据库。
下面的示例程序说明了如何进行此操作。这个程序需要一个 XML-SOURCE文档并解析它寻找interst事件(例如'b'标签)。当这样的标签 发现它开始构建一个片段文档(XML-FRAGMENT),直到找到结束标记。在 此时输出片段并开始搜索下一个片段。
IDENTIFICATION DIVISION.
PROGRAM-ID. XMLTEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 XL PIC S9(4) BINARY.
01. PIC X.
88 XML-EXTRACT-NO VALUE 'N'.
88 XML-EXTRACT-YES VALUE 'Y'.
01.
05 XML-FRAGMENT PIC X(8000).
05 XML-CHARS PIC S9(4) BINARY.
01 XML-SOURCE PIC X(8000).
PROCEDURE DIVISION.
MAINLINE SECTION.
MOVE '<a><b><c>Content</c><c>More content</c></b></a>'
TO XML-SOURCE
SET XML-EXTRACT-NO TO TRUE
XML PARSE XML-SOURCE
PROCESSING PROCEDURE XTRACT
GOBACK
.
XTRACT SECTION.
COMPUTE XL = FUNCTION LENGTH (XML-TEXT)
EVALUATE XML-EVENT
WHEN 'START-OF-ELEMENT'
*
* New XML element: Ignore it, add to existing fragment
* or start a new fragment...
*
IF XML-TEXT(1:XL) = 'b' OR XML-EXTRACT-YES
IF XML-EXTRACT-NO
MOVE ZERO TO XML-CHARS
SET XML-EXTRACT-YES TO TRUE
END-IF
STRING '<' XML-TEXT(1:XL) '>' DELIMITED BY SIZE
INTO XML-FRAGMENT(XML-CHARS + 1 : XL + 2)
COMPUTE XML-CHARS = XML-CHARS + XL + 2
END-IF
WHEN 'END-OF-ELEMENT'
*
* End of event: Add to XML fragment, ignore fragment or
* output complete fragment and start search
* for a new one...
*
IF XML-EXTRACT-YES
STRING '</' XML-TEXT(1:XL) '>' DELIMITED BY SIZE
INTO XML-FRAGMENT(XML-CHARS + 1 : XL + 3)
COMPUTE XML-CHARS = XML-CHARS + XL + 3
END-IF
IF XML-TEXT(1:XL) = 'b'
*
* End of fragment write to database (or whatever)
*
DISPLAY XML-FRAGMENT(1:XML-CHARS)
SET XML-EXTRACT-NO TO TRUE
END-IF
WHEN 'CONTENT-CHARACTERS'
*
* Add event data to fragment or just ignore it...
*
* Depening on the structure of your XML docuemnt you may
* need to react to addtional EVENTS such as CDATA to ensure
* proper tag construction.
*
IF XML-EXTRACT-YES
MOVE XML-TEXT(1:XL) TO XML-FRAGMENT(XML-CHARS + 1 : XL)
COMPUTE XML-CHARS = XML-CHARS + XL
END-IF
END-EVALUATE
.
此程序示例的输出是:
<b><c>Content</c><c>More content</c></b>
这不是您可能一直在寻找的单行解决方案,但您必须记住这是COBOL!
答案 2 :(得分:1)
在任何语言中,XML解析都有点棘手。我建议为您的特定COBOL环境找到解析器库。 This article简要概述了XML解析格局。考虑一下是否需要传递XML文件,随意提取所需信息(SAX方法适合您)或者是否要将XML加载到内存中并遍历其结构(您希望访问DOM [文档对象模型])。
事实上,您的COBOL方言可能有XML support built in(我的旧COBOL 85编译器没有的东西)和XML PARSE
语句。
答案 3 :(得分:0)
我现在可能有点迟到了,但是我们使用Redvers COBOL XML Interface解析器,它具有“ASIS”功能,可以将节点/父元素的整个内容读入单个COBOL字帖字段 - 完成任何XML标记和从属元素。这是一个DOM风格的解析器。生成器模块可以执行相反的操作,使您能够将预先准备好的XML加载到实例文档。