Snowflake cloud data platform json字段中的XML解析问题

Snowflake cloud data platform json字段中的XML解析问题,snowflake-cloud-data-platform,Snowflake Cloud Data Platform,我有一个json列,其中有一个XML字段我正试图解析 { "guid": "ba410633-d191-deab-fe63-23f732c517aa", "id": 1847510, "request":<?xml version='1.0' encoding='UTF-8'?><ConnectRequest xmlns='http://www.acme.com/NetConnect'

我有一个json列,其中有一个XML字段我正试图解析

{
  "guid": "ba410633-d191-deab-fe63-23f732c517aa",
  "id": 1847510,
  "request":<?xml version='1.0' encoding='UTF-8'?><ConnectRequest xmlns='http://www.acme.com/NetConnect' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.acme.com/API'><EAI>QWE</EAI><DBHost>TEST</DBHost><ReferenceId>aa</ReferenceId><Request xmlns='http://www.acme.com' version='1.0'><Products><PreciseIDServer><XMLVersion>5.0</XMLVersion><Subscriber><Preamble>ABC</Preamble><OpInitials>BCD</OpInitials><SubCode>2436170</SubCode></Subscriber></PreciseIDServer></Products></Request></ConnectRequest>"
}
这是一个数据类型问题吗?我能够使用相同的xmlget解析表中的另一列,该表有一个包含xml数据的变量列

with 
XML(DBHOST, PRODUCTS, PRECISEIDSERVER, SUBCODE) as
(
select  get(xmlget(parse_xml(json_field:request::string), 'DBHost'), '$')::string as DBHOST,
        get(xmlget(parse_xml(json_field:request::string), 'Request'), '$')::string as PRODUCTS,
        get(xmlget(parse_xml(PRODUCTS::string), 'PreciseIDServer'), '$')::string as PreciseIDServer,
        get(xmlget(parse_json(PreciseIDServer)[1], 'SubCode'), '$')::int     as SourceCode
from MY_TABLE
)
select DBHOST, SUBCODE from XML;
XMLGET将以这种方式在只包含XML的变量列上工作。在本例中,XML不是变体。JSON是变量,XML是属性之一。它需要作为字符串属性处理,然后作为XML进行操作。为此,您需要使用::string从JSON属性转换它。然后需要使用PARSE_XML将字符串转换为变量。最后,您可以对PARSE_XML生成的变量使用xmlget,并将GET与$final参数一起使用,以指示您只需要值,而不是开始和结束标记。字符串将最终结果转换为字符串,这样它就不会被双引号括起来

注意:示例xml中缺少一个close标记,在使用PARSE_xml函数时失败。我为测试添加了close标签。XML必须有效才能从字符串转换为XML变量


编辑:更新到CTE以添加子代码的解析。要获得嵌套了几层的XML节点,一个好的方法是使用CTE在列中一步一步地选择您想要的节点。

谢谢,我认为它与数据类型相关,这很有效。我还需要获取
子代码
您能帮上忙吗?当然。。。问题是xmlget不支持点表示法,因此它必须嵌套。太多的嵌套在另一个内部变得不可读,因此CTE是一种可行的方法。我更新了我的答案,使用CTE添加子代码,并逐步进行XML解析。我惊讶地看到
parse_json(precisedserver)
为什么precisedserver节点是json?我不太确定为什么,但如果将CTE的最后一行更改为“select*from XML”,您将看到precisedserver被解析为json。将它转移到jsonlint.com有助于格式化它,这表明它是一个数组。[1]取出数组的第二个成员,该成员包含SubCode属性。
select xmlget(request, 'DBHost'):"$" as DBHost
from (select json_field:request::variant request from table)
with 
XML(DBHOST, PRODUCTS, PRECISEIDSERVER, SUBCODE) as
(
select  get(xmlget(parse_xml(json_field:request::string), 'DBHost'), '$')::string as DBHOST,
        get(xmlget(parse_xml(json_field:request::string), 'Request'), '$')::string as PRODUCTS,
        get(xmlget(parse_xml(PRODUCTS::string), 'PreciseIDServer'), '$')::string as PreciseIDServer,
        get(xmlget(parse_json(PreciseIDServer)[1], 'SubCode'), '$')::int     as SourceCode
from MY_TABLE
)
select DBHOST, SUBCODE from XML;