2016-04-25 40 views
0

我有一个XML文件列表,需要使用MR代码进行解析。解析MapReduce中的XML文件

xml文件的样本是在下面

<tns:envelope xmlns:tns="http://abcd.com/schemas/envelope/v3_0" xmlns:xsi="http://www.abcd.org/2001/XMLSchema-instance" version="3.0"> 
    <tns:header> 
     <tns:type>response</tns:type> 
     <tns:service> 
      <tns:name>Value1</tns:name> 
      <tns:version>3.0</tns:version> 
     </tns:service> 
     <tns:originator>Value2</tns:originator> 
     <tns:businessProcessName>Value3</tns:businessProcessName> 
     <tns:sequenceNumber>value3</tns:sequenceNumber> 
     <tns:transactionReference>abcdef12345</tns:transactionReference> 
     <tns:expirationSeconds>1200</tns:expirationSeconds> 
     <tns:additionalParameters> 
      <tns:param> 
       <tns:name>notificationURL</tns:name> 
       <tns:value>https://url1</tns:value> 
      </tns:param> 
      <tns:param> 
       <tns:name>ConsumingCallbackURL</tns:name> 
       <tns:value>https://url2</tns:value> 
      </tns:param> 
     </tns:additionalParameters> 
     <tns:result> 
      <tns:status>success</tns:status> 
      <tns:provider>ABC</tns:provider> 
     </tns:result> 
     <tns:requestDateTime>2016-02-16T08:12:17.827Z</tns:requestDateTime> 
    </tns:header> 
    <tns:body></tns:body> 
</tns:envelope>   

现在我有哪些地方需要分析感兴趣的标签保持一个配置文件。样品标签名称给出像下面

/envelope/version 
/envelope/header/type 
/envelope/header/service/name 
/envelope/header/additionalParameters/param/name 
/envelope/header/additionalParameters/param/value 

预期产量将是像下面

/envelope/version /envelope/header/type /envelope/header/service/name /envelope/header/additionalParameters/param/name /envelope/header/additionalParameters/param/value 
     3.0    response     Value1        notificationURL         https://url1 
     3.0    response     Value1       ConsumingCallbackURL        https://url2 

我可以得到一个样本代码来解析XML并得到范例所需的输出。

+0

你的文件不够大需要mapreduce,也没有明确的缩小阶段。您正在跨文件映射XML解析器。 –

+0

这只是一个示例文件。每个文件大小为300KB,我们必须每天解析大约500K个这样的文件,所以我们认为MR应该是最好的选择。你能建议还能做些什么吗? –

+0

您是否首先在单个文件上创建了概念证明(没有mapreduce),因为这确实是您所需要的。 –

回答

0

存储数据的格式在XML等半结构化数据的情况下非常重要。看看示例XML数据,我只能假设它是某种web服务日志。我可以给你两个不同的方案在hadoop中处理XML文件的例子。

  1. 如果你有在XML文件是如何存储你可以把下面的格式(每个节点由换行符分离)的控制。您可以使用默认的hadoop TextInputFormat来读取每一行。

    <tns:envelope .... </tns:envelope>
    <tns:envelope .... </tns:envelope>
    <tns:envelope .... </tns:envelope>

示例代码:

public static class XMLDataMap extends Mapper<LongWritable, Text, Text, Text> { 

@Override 
protected void map(LongWritable key, 
         Text value, Mapper.Context context) throws Exception { 
    //read each line of XML data 
    String xmlDataLine = value.toString(); 
    String tagName = ""; 
    String tagValue = ""; 

//implement XML parsing logic below 
//I recommend using StAX parser, you can use DOM as well or already implemented parsing logic here 

//tagName = parse logic 
//tagValue = parse logic 

context.write(tagName, tagValue); 

} 

注:如果你没有在如何将数据存储控制和XML数据相当印刷(与提供的样本格式相同),则可以删除换行符并使其看起来像上面的格式。这样可以确保xml数据有效(不缺少标签)并使用可用的库来解析xml。

  1. 如果XML按以下格式级联,则会变得更有趣。您必须实现自定义InputFormat以将级联XML拆分为多个<tns:envelope .... </tns:envelope>。不用担心,我们有一个适用于这种XML格式的XmlInputFormat;最初为Apache Mahout项目创建,但现在有多个版本。

<cascadedXML>
<tns:envelope .... </tns:envelope>
<tns:envelope .... </tns:envelope>
<tns:envelope .... </tns:envelope>
.....
</cascadedXML>

OR

<cascadedXML><tns:envelope .... </tns:envelope><tns:envelope ....</tns:envelope><tns:envelope .... </tns:envelope> ..........</cascadedXML>

注:我建议在看,我已经回答了类似的问题几个月前的计算器链接(Not executing my hadoop mapper class while parsing xml in hadoop using XMLInputFormat)。

此外,请参阅Alex Holmes的书中的Hadoop实践和示例代码(Hadoop In Practice Github)以获得更多的信息。

+0

我不认为stax是理想的,因为许多复杂的xpath表达式意味着难以识别的脆弱代码 –