在 Hive 中,如何在 XML 中多次出现的相同父标签下分解相同的子标签?

问题描述

在下面的 Hive 查询中,XML 由 Parents 标签组成,其中包含 4 个 Parent 家族和 4 个 ParentArray 家族。在每个 ParentArray 下,有 ParentFieldArray 次出现,由相同的 Name 和 Value 标记ABCD111111 组成。 ).

with your_data as (
select  '<Parents>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
</Parents>' as xmlinfo
)
select name,pos+1 as pos,value
  from your_data d
       lateral view outer posexplode(XPATH(xmlinfo,'Parents/Parent/ParentArray/ParentFieldArray/Name/text()')) pf as  pos,Name
       lateral view outer explode(XPATH(xmlinfo,concat('Parents/Parent/ParentArray/ParentFieldArray[',pf.pos+1,'][Name="',pf.Name,'"]/Value/string/text()'))) vl as value;

上述查询正在填充第 1 个索引本身下的所有“111”行以及索引 2、3 和 4 下的 NULL 值。

查询的预期输出

name    pos value
ABCD    1   111
ABCD    2   111
ABCD    3   111
ABCD    4   111

解决方法

这是 XPATH 中的一个错误。 [] 优先并产生奇怪的结果。使用括号。

with your_data as (
select  '<Parents>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
    <Parent>
        <ParentArray>
            <ParentFieldArray>
                <Name>ABCD</Name>
                <Value>
                    <string>111</string>
                </Value>
            </ParentFieldArray>
        </ParentArray>
    </Parent>
</Parents>' as xmlinfo
)
select  pos+1 as pos,Name,Value
  from your_data d
       lateral view outer posexplode(XPATH(xmlinfo,'Parents/Parent/ParentArray/ParentFieldArray/Name/text()')) pf as  pos,Name
       lateral view outer explode(XPATH(xmlinfo,concat('((Parents/Parent/ParentArray/ParentFieldArray)[',pf.pos+1,'])[Name="',pf.Name,'"]/Value/string/text()'))) vl as value
      ;

结果:

pos name    value
1   ABCD    111
2   ABCD    111
3   ABCD    111
4   ABCD    111