自己写一个docx格式的解析器

众所周知,docx格式是国际软件巨头-微软为其自家产品Word所定义的一个文件格式,当然docx这种格式已经有很多很多的解析库可用了,但是你有没有想过自己一个docx的解析器呢?

首先,我们先做一个小小的实验,准备一个docx的文件,比如下面这个:

先用记事本打开,不出意外的话,应该是下面的结果:

但是,如果我们用另一种软件,比如7zip打开,会是什么情况呢?结果如下

很显然,docx文件格式是一种压缩文档格式,而这个压缩文档里面以xml的形式定义了文档的样式,文本和其他的内容

 

正常来说,一个docx压缩文档包含以下结构:

docProps
    app.xml
    core.xml
word
    theme                    //主题文件夹
        theme1.xml
    _rels
        document.xml.rels
    document.xml            //包含文档内容的xml文件,主要是解析它
    fontTable.xml            
    setting.xml             //word文档的设置信息
    styles.xml
    webSettings.xml
_rels
    .rels
[Content_Types].xml

既然docx的本质不过是一个zip格式的压缩文件,而我们又清楚了docx的格式,那么编写一个parser岂不是易如反掌的事情 :)

 

我们先看看word里面的内容:

再看document.xml文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" 
            xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" 
            xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" 
            xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" 
            xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" 
            xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" 
            xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" 
            xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" 
            xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" 
            xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" 
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" 
            xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" 
            xmlns:o="urn:schemas-microsoft-com:office:office" 
            xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" 
            xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" 
            xmlns:v="urn:schemas-microsoft-com:vml" 
            xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" 
            xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" 
            xmlns:w10="urn:schemas-microsoft-com:office:word" 
            xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
            xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" 
            xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" 
            xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" 
            xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" 
            xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" 
            xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" 
            xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" 
            xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" 
            mc:Ignorable="w14 w15 w16se w16cid wp14">
  <w:body>
    <w:p w14:paraId="487FD595" w14:textId="088DF81C" w:rsidR="0096521E" w:rsidRDefault="006C2D61">
      <w:r>
        <w:rPr>
          <w:rFonts w:hint="eastAsia"/>
        </w:rPr>
        <w:t>11111</w:t>
      </w:r>
      <w:bookmarkStart w:id="0" w:name="_GoBack"/>
      <w:bookmarkEnd w:id="0"/>
    </w:p>
    <w:sectPr w:rsidR="0096521E">
      <w:pgSz w:w="11906" w:h="16838"/>
      <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/>
      <w:cols w:space="425"/>
      <w:docGrid w:type="lines" w:linePitch="312"/>
    </w:sectPr>
  </w:body>
</w:document>

w:document标记没什么好说的,就是声明一个document的根类,当然它里面有一堆namespace的声明,看着挺心烦的。。。

w:body标记,就是声明文档的主体部分

w:p标记,标记一个段落

w:r标记,标记一行

w:rPr标记

w:t标记,标记一个文本,我们的老朋友"11111"就在这里

w:bookmarkStart标记,书签起始标记

w:bookmarkEnd标记,书签终止标记

w:secPr标记

w:pgSz标记,页面大小标记,其中w:w表示宽度,w:h表示高度

w:pgMar标记

w:cols标记

w:docGrid标记

作为最简单的文本解析,我们只需定位到w:body标记,读出所有的w:p标记,然后挨个遍历w:p标记,从w:p标记解析出w:t标记,这样就能获取到相应的文本内容

如果我们能够处理docx文档里面的所有的内容,或许你也可以写一个word软件来 :)

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值