我们正在努力在Hive表中加载半结构化XML文件。这些是零售购买数据。
我已经附上了一个样本XML文件,以了解数据的外观以及我用来读取该XML文件的Hive表定义。
对于XML中的每个购物篮,该文件在“投标”下都有多个“付款”和“金额”部分。例如,客户可以用现金,EFTPOS,信用卡,会员卡付款,或者有时可以结合使用。
从附加的XML读取数据时,结果显示Payment列与XML中的条目合并,对于“ Amt”,它显示NULL。
我了解到我用来读取数据的表格并非100%正确。
请让我知道如何使用xpath函数为相同元素名称“ Payment”和“ Amt”创建多个记录
我试图在Internet上找到一些相同的文档,却找不到与我的情况类似的任何东西。
样本数据:
<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
答案 0 :(得分:1)
仅获取一个字段
您可以使用下标运算符([])来解析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()",
这将为您提供以下值。
同时获取两个字段
如果要将两个字段都作为数组的一部分,则需要将这些字段定义为数组,并且在选择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;
输出将如前所述