Snowflake XML 解析:提取 snowflake sql 中标签值的属性

Snowflake XML parsing: extract attribute of a tag value in snowflake sql

  <ROOM name="Closet">
    <ITEMS>
      <ITEM ageM="6" brand="Ross'" costToReplace="25" desc="Sweater shawl" id="11" lineNum="11" method="2" purchasedFrom="Ross'" qtyLost="1" use="1">
        <IMAGES></IMAGES>
        <ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
      </ITEM>
      <ITEM ageY="2" brand="GAP" costToReplace="20" desc="white long sleeve shirt" id="12" lineNum="12" method="2" purchasedFrom="GAP" qtyLost="1">
        <IMAGES></IMAGES>
        <ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
      </ITEM>
    </ITEMS>
  </ROOM>
  <ROOM name="Kitchen">
    <ITEMS>
      <ITEM ageM="6" ageY="1" brand="Pier 1 Imports" costToReplace="30" desc="Wine decanter" id="13" lineNum="13" method="3" purchasedFrom="Pier 1 Imports" qtyLost="1" use="1">
        <IMAGES></IMAGES>
        <ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
      </ITEM>
    </ITEMS>
  </ROOM>
</ROOMS>

ID return 值假设为 11、12、13,但我只得到 11、12。

我的代码:

栏名是房间, Table 名字是 item_xml

select 
  rs.value:"@id" ::string
from item_xml,  LATERAL FLATTEN( INPUT => XMLGET(XMLGET(item_xml.room, 'ROOM'),'ITEMS'):"$") rs;

有人可以帮助我吗?非常感谢!

问题是您要遍历两个数组,但只有一个 FLATTEN,

因此你需要另一个 FLATEN,但这里的诀窍是“厨房”在 ITEMS 中只有一个项目,大多数 XML 解析不正确地映射到一个对象(也就是这种情况也发生在雪花中)。

因此,在使用之前,您必须将“items”的输出从“Room”转换为数组:

select
    i.value:"@id" ::string
from item_xml
    ,LATERAL FLATTEN( INPUT => room:"$") as r
    ,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;

给出:

I.VALUE:"@ID" ::STRING
11
12
13

技术上你真的应该包装所有数组,所以当数据是单个项目时,你 SQL 不会爆炸。因此你的解决方案应该是:

select
    i.value:"@id" ::string
from item_xml
    ,LATERAL FLATTEN( INPUT => to_array(room:"$")) as r
    ,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;