首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >当没有特定的字段来参数化解析的字符串时,如何解析XML家族中的字段&映射到它的右父级?

当没有特定的字段来参数化解析的字符串时,如何解析XML家族中的字段&映射到它的右父级?
EN

Stack Overflow用户
提问于 2021-08-07 10:10:55
回答 2查看 61关注 0票数 1

在我的输入XML中,父代中有多个“父代”家庭。在每个父代中,ChildRoots中可以有单个或多个"ChildRoot“系列。在这个层次结构中有4个字段需要解析。在Hive XPATH函数的帮助下,如何在不发生交叉联接的情况下实现这一点?在这种情况下,没有特定的字段来参数化解析的字符串,以便映射到它的右父级(Parents/ parent /ChildRoot/ChildRoot/)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Parents>
    <Parent>
        <ChildRoots>
            <ChildRoot>
                <FieldA>Field A info1</FieldA>
                <FieldB>Field B info1</FieldB>
                <FieldC>Field C info1</FieldC>
                <FieldD>Field D info1</FieldD>
            </ChildRoot>
        </ChildRoots>
    </Parent>
    <Parent>
        <ChildRoots>
            <ChildRoot>
                <FieldA>Field A info2</FieldA>
                <FieldC>Field C info2</FieldC>
                <FieldD>Field D info2</FieldD>
            </ChildRoot>
            <ChildRoot>
                <FieldA>Field A info3</FieldA>
                <FieldB>Field B info3</FieldB>
                <FieldD>Field D info3</FieldD>
            </ChildRoot>
        </ChildRoots>
    </Parent>
</Parents>

预期输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FieldA          FieldB          FieldC          FieldD
Field A info1   Field B info1   Field C info1   Field D info1
Field A info2                   Field C info2   Field D info2
Field A info3   Field B info3                   Field D info3
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-08 05:53:32

使用count() XPATH函数可以计算每个级别上的元素数量。例如,XPATH_INT(xml, 'count(/Parents/Parent)')提供了2。使用横向视图posexplode为每个级别生成行,并使用分解位置参数化XPATH,因此所有这些XPATH都将具有一致的位置索引,并且不会发生交叉连接。

在这个例子中,<Parent>只有一个子<ChildRoots>,如果它是每个父<ChildRoots>中唯一的一个,你可以删除计数和分解的计算,这将会简化代码。我的代码允许每个<Parent>有多个<ChildRoots>

演示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
with mytable as (
select '<Parents>
    <Parent>
        <ChildRoots>
            <ChildRoot>
                <FieldA>Field A info1</FieldA>
                <FieldB>Field B info1</FieldB>
                <FieldC>Field C info1</FieldC>
                <FieldD>Field D info1</FieldD>
            </ChildRoot>
        </ChildRoots>
    </Parent>
    <Parent>
        <ChildRoots>
            <ChildRoot>
                <FieldA>Field A info2</FieldA>
                <FieldC>Field C info2</FieldC>
                <FieldD>Field D info2</FieldD>
            </ChildRoot>
            <ChildRoot>
                <FieldA>Field A info3</FieldA>
                <FieldB>Field B info3</FieldB>
                <FieldD>Field D info3</FieldD>
            </ChildRoot>
        </ChildRoots>
    </Parent>
</Parents>
' as xml
)

select --Get ChildRoot count and generate rows with position index, build final XPATH
       --xml, parent_pos, ChildRoots_pos, 
       --cr.pos+1 as ChildRoot_pos, --this expression used in xpath as is:
       XPATH_STRING(xml, concat('/Parents/Parent[',parent_pos,']/ChildRoots[',ChildRoots_pos,']/ChildRoot[',cr.pos+1,']/FieldA/text()')) as FieldA,
       XPATH_STRING(xml, concat('/Parents/Parent[',parent_pos,']/ChildRoots[',ChildRoots_pos,']/ChildRoot[',cr.pos+1,']/FieldB/text()')) as FieldB,
       XPATH_STRING(xml, concat('/Parents/Parent[',parent_pos,']/ChildRoots[',ChildRoots_pos,']/ChildRoot[',cr.pos+1,']/FieldC/text()')) as FieldC,
       XPATH_STRING(xml, concat('/Parents/Parent[',parent_pos,']/ChildRoots[',ChildRoots_pos,']/ChildRoot[',cr.pos+1,']/FieldD/text()')) as FieldD
from
( --Get ChildRoots count and generate rows with position index
select xml, parent_pos, crs.pos+1 as ChildRoots_pos
       --XPATH_INT(xml, concat('count(/Parents/Parent[',parent_pos,']/ChildRoots)')) as ChildRoots_cnt  
from
  ( --Get Parent count and generate rows with position index
    select  xml, p.pos+1 as parent_pos
          --XPATH_INT(xml, 'count(/Parents/Parent)') as Parent_cnt
     from mytable lateral view outer posexplode(split(space(XPATH_INT(xml, 'count(/Parents/Parent)')-1),'')) p as  pos, x
   ) p lateral view outer posexplode(split(space(XPATH_INT(xml, concat('count(/Parents/Parent[',parent_pos,']/ChildRoots)'))-1),'')) crs as  pos, x 
) crs lateral view outer posexplode(split(space(XPATH_INT(xml, concat('count(/Parents/Parent[',parent_pos,']/ChildRoots[',ChildRoots_pos,']/ChildRoot)'))-1),'')) cr as  pos, x        

结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fielda           fieldb           fieldc           fieldd
Field A info1    Field B info1    Field C info1    Field D info1
Field A info2                     Field C info2    Field D info2
Field A info3    Field B info3                     Field D info3  
票数 1
EN

Stack Overflow用户

发布于 2021-08-07 12:28:30

所需字段可按其名称查找,如下所示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
xmllint --xpath '/Parents/Parent[1]/ChildRoots/ChildRoot[1]/child::*[name()="FieldA" or name()="FieldB" or name()="FieldC" or name()="FieldD"]' test.xml ; echo
# <FieldA>Field A info1</FieldA><FieldB>Field B info1</FieldB><FieldC>Field C info1</FieldC><FieldD>Field D info1</FieldD>

xmllint --xpath '/Parents/Parent[2]/ChildRoots/ChildRoot[1]/child::*[name()="FieldA" or name()="FieldB" or name()="FieldC" or name()="FieldD"]' test.xml ; echo
# <FieldA>Field A info2</FieldA><FieldC>Field C info2</FieldC><FieldD>Field D info2</FieldD>

xmllint --xpath '/Parents/Parent[2]/ChildRoots/ChildRoot[2]/child::*[name()="FieldA" or name()="FieldB" or name()="FieldC" or name()="FieldD"]' test.xml ; echo
# <FieldA>Field A info3</FieldA><FieldB>Field B info3</FieldB><FieldD>Field D info3</FieldD>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68694975

复制
相关文章

相似问题

领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文