遍历 xmlnsc 树并删除 ESQL 中的名称空间
Walk trough xmlnsc tree and remove namespaces in ESQL
编辑: 通过删除 xmlns,我试图解决映射节点无法解析包含命名空间的字段的输入消息的问题。输入正文是手动设置的 - 而不是来自 XSD。当手动从文件中删除名称空间时,一切正常。但是当我使用 ESQL 脚本时,它会因为一些我不知道的原因而停止工作。
您好,我收到 XML 消息,我需要从中删除命名空间。我想做的是递归遍历 XML 树并删除 xmlns 属性(如果存在)。不幸的是,当我尝试执行 SET element = NULL
时,我的循环不会转到下一个元素 MOVE element NEXTSIBLING
。我尝试做 DELETE FIELD element
但效果相同。
这是我的完整代码:
CREATE COMPUTE MODULE test_Compute1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
DECLARE blobMsg BLOB Environment.BLOB.BLOB ;
CREATE LASTCHILD OF Environment.Variables.inpMsg DOMAIN ('XMLNSC') NAME 'XMLNSC';
CREATE LASTCHILD OF Environment.Variables.inpMsg.XMLNSC PARSE(blobMsg OPTIONS FolderBitStream CCSID InputRoot.Properties.CodedCharSetId FORMAT 'XMLNSC');
SET Environment.Variables.statusRes.statusCode = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpCode;
SET Environment.Variables.statusRes.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpMessage;
SET Environment.Variables.statusRes.additionalStatus.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.moreInformation;
CALL NavigateTree(Environment.Variables.inpMsg.XMLNSC);
RETURN TRUE;
END;
CREATE PROCEDURE NavigateTree(IN root REFERENCE)
BEGIN
DECLARE element REFERENCE TO root;
DECLARE hint CHARACTER;
DECLARE test CHARACTER;
SET test = '';
SET hint = '';
MOVE element FIRSTCHILD;
-----------
IF LASTMOVE(element) THEN
SET hint = 'has children';
ELSE
IF FIELDNAME(element) = 'xmlns' THEN
DELETE FIELD element;
END IF;
END IF;
WHILE LASTMOVE(element) DO
-- not working awell:
-- DECLARE space1 NAMESPACE 'namespace1';
-- SET element.(XML.NamespaceDecl)* = NULL;
DECLARE nameField2 CHARACTER FIELDNAMESPACE(element);
DECLARE nameField CHARACTER FIELDNAME(element);
DECLARE ifhint CHARACTER;
CALL NavigateTree(element);
MOVE element NEXTSIBLING;
END WHILE;
SET hint = 'finished';
END;
END MODULE;
你知道我该怎么做吗?
编辑:
CREATE COMPUTE MODULE test_Compute1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
DECLARE blobMsg BLOB Environment.BLOB.BLOB ;
CREATE LASTCHILD OF Environment.Variables.inpMsg DOMAIN ('XMLNSC') NAME 'XMLNSC';
CREATE LASTCHILD OF Environment.Variables.inpMsg.XMLNSC PARSE(blobMsg OPTIONS FolderBitStream CCSID InputRoot.Properties.CodedCharSetId FORMAT 'XMLNSC');
SET Environment.Variables.statusRes.statusCode = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpCode;
SET Environment.Variables.statusRes.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpMessage;
SET Environment.Variables.statusRes.additionalStatus.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.moreInformation;
CALL StripNamespaces(Environment.Variables.inpMsg);
RETURN TRUE;
END;
CREATE PROCEDURE StripNamespaces(IN fieldRef REFERENCE)
BEGIN
IF FIELDTYPE(fieldRef) IN (XMLNSC.NamespaceDecl, XMLNSC.SingleNamespaceDecl) THEN
DELETE FIELD fieldRef;
RETURN;
END IF;
DECLARE childRef REFERENCE TO fieldRef;
MOVE childRef FIRSTCHILD;
WHILE LASTMOVE(childRef) DO
DECLARE currentChildRef REFERENCE TO childRef;
MOVE childRef NEXTSIBLING;
CALL StripNamespaces(currentChildRef);
END WHILE;
END;
END MODULE;
XML 作为输入文件进入映射节点(手动编辑):
<?xml version="1.0" encoding="utf-8"?>
<Receive >
<messageData>
<CD >
<EXP />
<EXAMPLE />
</CD>
<XRP >
<EX1>
<SEG>string</SEG>
<SEG2>integer</SEG2>
</EX1>
<ARRAY>
<AR1>string</AR1>
<AR2 />
</ARRAY>
<ARRAY>
<AR1>integer</AR1>
<AR2 />
</ARRAY>
</XRP>
</messageData>
</Receive>
XML 无效(映射节点在经过上述解析后无法正确处理):
<?xml version="1.0" encoding="utf-8"?>
<Receive xmlns="namespace">
<messageData>
<CD xmlns="namespace2">
<EXP xmlns="namespace3" />
<EXAMPLE xmlns="namespace3" />
</CD>
<XRP xmlns="namespace2">
<EX1>
<SEG>string</SEG>
<SEG2>integer</SEG2>
</EX1>
<ARRAY>
<AR1>string</AR1>
<AR2 />
</ARRAY>
<ARRAY>
<AR1>integer</AR1>
<AR2 />
</ARRAY>
</XRP>
</messageData>
</Receive>
在这两种情况下,调试器在经过相同的解析器后显示相同的树结构:
Variables
inpMsg
XMLNSC
Receive
messageData
CD
EXP
EXAMPLE
XRP
EX1
SEG:CHARACTER:string
SEG2:CHARACTER:integer
ARRAY
AR1:CHARACTER:string
AR2
ARRAY
AR1:CHARACTER:integer
AR2
字段删除后必须退出递归函数。
我们是这样做的:
CREATE PROCEDURE StripNamespaces(IN fieldRef REFERENCE)
BEGIN
IF FIELDTYPE(fieldRef) IN (XMLNSC.NamespaceDecl, XMLNSC.SingleNamespaceDecl) THEN
DELETE FIELD fieldRef;
RETURN;
ELSEIF FIELDNAMESPACE(fieldRef) <> '' THEN
SET fieldRef NAMESPACE = '';
END IF;
DECLARE childRef REFERENCE TO fieldRef;
MOVE childRef FIRSTCHILD;
WHILE LASTMOVE(childRef) DO
DECLARE currentChildRef REFERENCE TO childRef;
MOVE childRef NEXTSIBLING;
CALL StripNamespaces(currentChildRef);
END WHILE;
END;
编辑: 通过删除 xmlns,我试图解决映射节点无法解析包含命名空间的字段的输入消息的问题。输入正文是手动设置的 - 而不是来自 XSD。当手动从文件中删除名称空间时,一切正常。但是当我使用 ESQL 脚本时,它会因为一些我不知道的原因而停止工作。
您好,我收到 XML 消息,我需要从中删除命名空间。我想做的是递归遍历 XML 树并删除 xmlns 属性(如果存在)。不幸的是,当我尝试执行 SET element = NULL
时,我的循环不会转到下一个元素 MOVE element NEXTSIBLING
。我尝试做 DELETE FIELD element
但效果相同。
这是我的完整代码:
CREATE COMPUTE MODULE test_Compute1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
DECLARE blobMsg BLOB Environment.BLOB.BLOB ;
CREATE LASTCHILD OF Environment.Variables.inpMsg DOMAIN ('XMLNSC') NAME 'XMLNSC';
CREATE LASTCHILD OF Environment.Variables.inpMsg.XMLNSC PARSE(blobMsg OPTIONS FolderBitStream CCSID InputRoot.Properties.CodedCharSetId FORMAT 'XMLNSC');
SET Environment.Variables.statusRes.statusCode = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpCode;
SET Environment.Variables.statusRes.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpMessage;
SET Environment.Variables.statusRes.additionalStatus.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.moreInformation;
CALL NavigateTree(Environment.Variables.inpMsg.XMLNSC);
RETURN TRUE;
END;
CREATE PROCEDURE NavigateTree(IN root REFERENCE)
BEGIN
DECLARE element REFERENCE TO root;
DECLARE hint CHARACTER;
DECLARE test CHARACTER;
SET test = '';
SET hint = '';
MOVE element FIRSTCHILD;
-----------
IF LASTMOVE(element) THEN
SET hint = 'has children';
ELSE
IF FIELDNAME(element) = 'xmlns' THEN
DELETE FIELD element;
END IF;
END IF;
WHILE LASTMOVE(element) DO
-- not working awell:
-- DECLARE space1 NAMESPACE 'namespace1';
-- SET element.(XML.NamespaceDecl)* = NULL;
DECLARE nameField2 CHARACTER FIELDNAMESPACE(element);
DECLARE nameField CHARACTER FIELDNAME(element);
DECLARE ifhint CHARACTER;
CALL NavigateTree(element);
MOVE element NEXTSIBLING;
END WHILE;
SET hint = 'finished';
END;
END MODULE;
你知道我该怎么做吗?
编辑:
CREATE COMPUTE MODULE test_Compute1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
DECLARE blobMsg BLOB Environment.BLOB.BLOB ;
CREATE LASTCHILD OF Environment.Variables.inpMsg DOMAIN ('XMLNSC') NAME 'XMLNSC';
CREATE LASTCHILD OF Environment.Variables.inpMsg.XMLNSC PARSE(blobMsg OPTIONS FolderBitStream CCSID InputRoot.Properties.CodedCharSetId FORMAT 'XMLNSC');
SET Environment.Variables.statusRes.statusCode = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpCode;
SET Environment.Variables.statusRes.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.httpMessage;
SET Environment.Variables.statusRes.additionalStatus.detail = Environment.Variables.inpMsg.XMLNSC.errorResponse.moreInformation;
CALL StripNamespaces(Environment.Variables.inpMsg);
RETURN TRUE;
END;
CREATE PROCEDURE StripNamespaces(IN fieldRef REFERENCE)
BEGIN
IF FIELDTYPE(fieldRef) IN (XMLNSC.NamespaceDecl, XMLNSC.SingleNamespaceDecl) THEN
DELETE FIELD fieldRef;
RETURN;
END IF;
DECLARE childRef REFERENCE TO fieldRef;
MOVE childRef FIRSTCHILD;
WHILE LASTMOVE(childRef) DO
DECLARE currentChildRef REFERENCE TO childRef;
MOVE childRef NEXTSIBLING;
CALL StripNamespaces(currentChildRef);
END WHILE;
END;
END MODULE;
XML 作为输入文件进入映射节点(手动编辑):
<?xml version="1.0" encoding="utf-8"?>
<Receive >
<messageData>
<CD >
<EXP />
<EXAMPLE />
</CD>
<XRP >
<EX1>
<SEG>string</SEG>
<SEG2>integer</SEG2>
</EX1>
<ARRAY>
<AR1>string</AR1>
<AR2 />
</ARRAY>
<ARRAY>
<AR1>integer</AR1>
<AR2 />
</ARRAY>
</XRP>
</messageData>
</Receive>
XML 无效(映射节点在经过上述解析后无法正确处理):
<?xml version="1.0" encoding="utf-8"?>
<Receive xmlns="namespace">
<messageData>
<CD xmlns="namespace2">
<EXP xmlns="namespace3" />
<EXAMPLE xmlns="namespace3" />
</CD>
<XRP xmlns="namespace2">
<EX1>
<SEG>string</SEG>
<SEG2>integer</SEG2>
</EX1>
<ARRAY>
<AR1>string</AR1>
<AR2 />
</ARRAY>
<ARRAY>
<AR1>integer</AR1>
<AR2 />
</ARRAY>
</XRP>
</messageData>
</Receive>
在这两种情况下,调试器在经过相同的解析器后显示相同的树结构:
Variables
inpMsg
XMLNSC
Receive
messageData
CD
EXP
EXAMPLE
XRP
EX1
SEG:CHARACTER:string
SEG2:CHARACTER:integer
ARRAY
AR1:CHARACTER:string
AR2
ARRAY
AR1:CHARACTER:integer
AR2
字段删除后必须退出递归函数。
我们是这样做的:
CREATE PROCEDURE StripNamespaces(IN fieldRef REFERENCE)
BEGIN
IF FIELDTYPE(fieldRef) IN (XMLNSC.NamespaceDecl, XMLNSC.SingleNamespaceDecl) THEN
DELETE FIELD fieldRef;
RETURN;
ELSEIF FIELDNAMESPACE(fieldRef) <> '' THEN
SET fieldRef NAMESPACE = '';
END IF;
DECLARE childRef REFERENCE TO fieldRef;
MOVE childRef FIRSTCHILD;
WHILE LASTMOVE(childRef) DO
DECLARE currentChildRef REFERENCE TO childRef;
MOVE childRef NEXTSIBLING;
CALL StripNamespaces(currentChildRef);
END WHILE;
END;