使用PIG实现XML扁平化:嵌套循环和父节点访问

使用PIG实现XML扁平化:嵌套循环和父节点访问,xml,hadoop,hive,apache-pig,bigdata,Xml,Hadoop,Hive,Apache Pig,Bigdata,我目前正试图在PIG脚本中使用XPath循环嵌套的XML元素,我面临一些限制。下面是我尝试做的一个虚拟示例: 我有一个如下所示的XML文件: <?xml version="1.0" encoding="UTF-8"?> <Log CPEID="1847671824" CUID="0" > <Event EventTime="2015-10-14T21:50:00"> <Action>A</Action>

我目前正试图在PIG脚本中使用XPath循环嵌套的XML元素,我面临一些限制。下面是我尝试做的一个虚拟示例:

我有一个如下所示的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<Log CPEID="1847671824" CUID="0" >
    <Event EventTime="2015-10-14T21:50:00">
        <Action>A</Action>
    </Event>
    <Event EventTime="2015-10-14T22:55:12">
        <Action>B</Action>
    </Event>
    <Event EventTime="2015-10-14T23:54:51">
        <Action>C</Action>
    </Event>
</Log>
如果使用加载程序中的“Log”元素加载XML文件(请参见下),则无法循环“Event”元素

如果使用“Event”元素加载XML文件,则无法访问父元素。(XMLLoader输出后的正常情况)

是否有人已经面临同样的问题,并有想法正确处理此示例?我知道UDF可以帮助我,但考虑到它必须易于维护,我更愿意只使用Pig/Hive,当然,如果可能的话

我的Pig脚本,仅访问第一个“Event”元素(在“Log”元素上循环):

结果(不是我想要的…见上文):


好吧,这可以用XSLT实现,而不是用普通的XPath=>在Linux机器上下载XML文件,在上面运行
xsltproc
,使用Pig进行后处理。或者,如果您知道最多可以有3个项目,则为“EventTime”和“Action”生成两个数组,然后用类似sthg的
concat(Log/Event[1]来分解它们/@EventTime,“:”,Log/Event[2]/@EventTime,“:”,Log/Event[3]/@EventTime)
等。感谢您的回复,确认我的结论。如前所述,这种转换必须易于维护,当然,如果可能的话,最好使用经典hadoop分发目录中包含的工具。现在最快的解决方案是使用Talend(带有XML解析器)将XML文件展平,然后将.csv复制到hadoop集群。事件的数量是无限的,因此不可能使用第二个选项。信息方面,我每天要处理50亿个文件,总大小约为10Go.5亿个微观文件-听起来你需要的是流式解决方案,而不是像Pig或Hive这样的批量解决方案。Talend绝不是一个“经典”的Hadoop工具,而Storm和Spark(还有Kafka)现在都包含在Hadoop发行版中……我完全同意你的看法。我们目前正在尝试几种解决方案。。其中之一是首先将1000个xml文件压缩成一个大文件,并以批处理模式处理较大的文件。对于500.000个文件,我们的处理时间约为55秒,每个“大文件”包含1000个文件。流媒体是下一步。
   CUID    |    CPEID    |      EventTime       |  Action
---------------------------------------------------------------
123456789  | 56431284132 | 2015-10-14T21:50:00  |    A
123456789  | 56431284132 | 2015-10-14T22:55:12  |    B
123456789  | 56431284132 | 2015-10-14T23:54:51  |    C
REGISTER 'piggybank.jar';
DEFINE XPath org.apache.pig.piggybank.evaluation.xml.XPath();

ALL_XMLs = LOAD 'test.xml' using org.apache.pig.piggybank.storage.XMLLoader('Log') as (x:chararray);
ALL_XMLs = LOAD 'test.xml' using org.apache.pig.piggybank.storage.XMLLoader('Element') as (x:chararray);
REGISTER 'piggybank.jar';
DEFINE XPath org.apache.pig.piggybank.evaluation.xml.XPath();

ALL_XMLs = LOAD 'test.xml'
using org.apache.pig.piggybank.storage.XMLLoader('Log') as (x:chararray);

Logs = FOREACH ALL_XMLs GENERATE
XPath(x, 'Log/@CUID'),
XPath(x, 'Log/@CPEID'),
XPath(x, 'Log/Event/@EventTime'),
XPath(x, 'Log/Event/Action');

DUMP Logs;
0;1847671824;2015-10-14T21:50:00;A