将xml文件加载到配置单元表

uubf1zoe  于 2021-06-01  发布在  Hadoop
关注(0)|答案(1)|浏览(442)

我们正在将一个半结构化的xml文件加载到配置单元表中。这些是零售购买数据。
我附加了一个示例xml文件,以了解数据的外观以及用于读取该xml文件的配置单元表定义。
对于xml中的每个篮子,该文件在“tender”下有多个payment and amount(amt)部分。例如,客户可以用现金、eftpo、信用卡、忠诚卡支付,有时也可以同时使用这些支付方式。
当从附加的xml中读取数据时,结果显示payment列与xml中的条目合并,对于'amt'它显示null。
我知道我用来读取数据的表格不是100%正确的。
请告诉我如何使用xpath函数为相同的元素名“payment”和“amt”创建多个记录
我试图在互联网上找到一些相同的文档,但找不到任何与我的场景类似的东西。
样本数据:

<Bskt>
  <TillNo>4</TillNo>
  <BsktNo>1747</BsktNo>
  <DateTime>2017-10-31T10:51:25.000+11:00</DateTime>
  <OpID>10115</OpID>
  <Tender>
    <PayType>CSH</PayType>
    <Amt>46.75</Amt>
  </Tender>
  <Tender>
    <PayType>ITMLOY</PayType>
    <Amt>0</Amt>
    <CardNo>2679911927</CardNo>
    <Program>SmartRewards</Program>
    <Earn>46.00</Earn>
    <Burn>0.00</Burn>
  </Tender>
</Bskt>
<Bskt>
  <TillNo>4</TillNo>
  <BsktNo>1748</BsktNo>
  <DateTime>2017-10-31T10:53:11.000+11:00</DateTime>
  <OpID>10115</OpID>
  <Tender>
    <PayType>CSH</PayType>
    <Amt>46.75</Amt>
  </Tender>
  <Tender>
    <PayType>ITMLOY</PayType>
    <Amt>0</Amt>
    <CardNo>2619183833</CardNo>
    <Program>SmartRewards</Program>
    <Earn>46.00</Earn>
    <Burn>0.00</Burn>
  </Tender>
</Bskt>
<Bskt>
  <TillNo>4</TillNo>
  <BsktNo>1753</BsktNo>
  <DateTime>2017-10-31T11:19:34.000+11:00</DateTime>
  <OpID>50056</OpID>
  <Tender>
    <PayType>CSH</PayType>
    <Amt>28.10</Amt>
  </Tender>
  <Tender>
    <PayType>ITMLOY</PayType>
    <Amt>0</Amt>
    <CardNo>8263734549</CardNo>
    <Program>SmartRewards</Program>
    <Earn>28.00</Earn>
    <Burn>0.00</Burn>
  </Tender>
</Bskt>

配置单元表:

CREATE EXTERNAL TABLE BASKET_TENDER (
`DateTime` string,
`BsktNo` double,
`TillNo` int,
`PayType` string,
`Amt` float,
`CardNo` string,
`Program` string,
`Earn` float,
`Burn` float
)

ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe'
WITH SERDEPROPERTIES (

"column.xpath.DateTime"="/Bskt/DateTime/text()",
"column.xpath.BsktNo"="/Bskt/BsktNo/text()",
"column.xpath.TillNo"="/Bskt/TillNo/text()",
"column.xpath.PayType"="/Bskt/Tender/Paytype/text()",
"column.xpath.CardNo"="/Bskt/Tender/CardNo/text()",
"column.xpath.Amt"="/Bskt/Tender/Amt/text()",
"column.xpath.Program"="/Bskt/Tender/Program/text()",
"column.xpath.Earn"="/Bskt/Tender/Earn/text()",
"column.xpath.Burn"="/Bskt/Tender/Burn/text()"
)

STORED AS INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
    OUTPUTFORMAT 
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' 
    LOCATION '<hdfs file location>'
    TBLPROPERTIES (
    "xmlinput.start"="<Bskt","xmlinput.end"="</Bskt>"
);

配置单元查询输出:

select * from BASKET_TENDER

2cmtqfgy

2cmtqfgy1#

仅获取一个字段
您可以使用下标运算符([])来解析xml。但是,请确保索引以1开头,而不是0。
在你的情况下,我想你想要第二审投标。然后使用以下xml路径。

"column.xpath.PayType"="/Bskt/Tender[2]/PayType/text()",
"column.xpath.CardNo"="/Bskt/Tender[2]/CardNo/text()",
"column.xpath.Amt"="/Bskt/Tender[2]/Amt/text()",

这将为您提供以下值。

两块地都要
如果希望将这两个字段都作为array的一部分,则需要将这些字段定义为array,并且在选择xpath时不提供任何下标运算符,如下所述

drop table temp.BASKET_TENDER;
CREATE EXTERNAL TABLE temp.BASKET_TENDER (
`DateTime` string,
`BsktNo` double,
`TillNo` int,
`PayType`  array<String>,
`Amt` array<float>,
`CardNo` array<string>,
`Program` string,
`Earn` float,
`Burn` float
)

ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe'
WITH SERDEPROPERTIES (

"column.xpath.DateTime"="/Bskt/DateTime/text()",
"column.xpath.BsktNo"="/Bskt/BsktNo/text()",
"column.xpath.TillNo"="/Bskt/TillNo/text()",
"column.xpath.PayType"="/Bskt/Tender/PayType/text()",
"column.xpath.CardNo"="/Bskt/Tender/CardNo/text()",
"column.xpath.Amt"="/Bskt/Tender/Amt/text()",
"column.xpath.Program"="/Bskt/Tender/Program/text()",
"column.xpath.Earn"="/Bskt/Tender/Earn/text()",
"column.xpath.Burn"="/Bskt/Tender/Burn/text()"
)

STORED AS INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
    OUTPUTFORMAT 
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' 
    LOCATION '/tmp/BASKET_TENDER'
    TBLPROPERTIES (
    "xmlinput.start"="<Bskt","xmlinput.end"="</Bskt>"
);

select * from temp.BASKET_TENDER;

输出如前所述

相关问题