场景

  1. 在开发生成docx文档时,也需要生成内部的word/document.xml文档, 而生成xml避免不了需要校验xml的元素标签完整性,即开始和结束标签匹配。如果每次生成docx文档还需要解压获取打开document.xml文件来手动判断有效性效率就太低了。前面讲过可以通过python来解压zip(docx)格式, 当然也可以通过python来校验生成的docx文档是否有损坏。

说明

  1. docx实际上就是zip格式, 我们可以把后缀名改为zip,之后就能解压出来一些文件,里面的文字部分就是存储在word/document.xml里的.

  2. 在没有python之前,可以通过微软的XML Notepad免费软件打开xml文档,根据弹出的错误提示窗口来判断XML文档哪里有问题。我这里说的XML文档都是上10M的,用普通的文档编辑器打开是看不出问题的。

  3. python可以使用xml.sax标准库模块来进行校验,速度快,内存使用少,无需生成庞大的DOM对象。

  4. xml.sax的错误提示最重要的是指示某行:某列出现什么错误: 比如
    error.xml:5:6: mismatched tag。但是这个错误提示并不全,最好能给出错误位置的前后100个字符,这样能方便推理出什么原因造成这个XML解析错误的. 我们可以通过错误提示的某行某列,某m行某n列即第m行,第n个字符,注意,并不是第n个字节,这对于中文多字节字符定位更加准确。

  5. 我这里写了一个方法charSeek来读取字符串到某行某列,并输出它的前后x个字符作为输出参考。注意,我们读取文本文件,内部是使用的TextIOBase,它不能使用文件对象的seek来跳转,因为它是跳转字节的;但是可以使用readxx(size)方法,它是读入指定个字符,通过readxx方法,我们可以实现定位到第m行第n列的字符。

例子

XmlValidator.py


from io import SEEK_CUR, SEEK_SET
from xml.sax.handler import ContentHandler
from xml.sax import SAXParseException, make_parser
import clickclass MyContentHandler(ContentHandler):def startElement(self, name, attrs):self.elementName = nameself.elementAttrs = attrsself.isElementStart = Trueself.elementConent = ""def endElement(self, name):self.elementName = nameself.isElementStart = Falsedef characters(self, content):if content != None:self.elementConent = contentdef printElement(elementName,isStartElement,elementAttris,elementContent):print("[<",end="")if not isStartElement:print("/",end="")print(elementName,end="")if(elementAttris != None):for key,value in elementAttris.items():print(" "+key+"="+value,end=" ")print(">",end="")if(elementContent != None):print(elementContent,end="")print("]")def charSeek(file,offset,maxOffsetLength):maxBuf = 1024if maxBuf > offset:maxBuf = offsetpos = 0line = ""while pos < offset:if (pos + maxBuf) > offset:maxBuf = offset - posline = file.readline(maxBuf)pos = pos + maxBufreturn line[-maxOffsetLength:]def readFileLineColumnContext(fileName,lineNumber,columnNumber,maxOffsetLength):# print("[File:%s]-[Line:%d]-[Column:%d]-[MaxOffsetLength:%d]" #     % (fileName,lineNumber,columnNumber,maxOffsetLength))with open(fileName,encoding="utf-8") as f:n = 1maxBuf = 1024line = ""while n < lineNumber:n = n +1lineEnd = Falsewhile not lineEnd:line = f.readline(maxBuf)# print(line)a = line[-1:]if a == "\n":lineEnd = Truebreak# f.seek是针对字节的,不要使用,不然如果位置在一个多字节字符的中间,read解码utf-8字符会报错.preLine = charSeek(f,columnNumber,maxOffsetLength)b1 = f.read(maxOffsetLength)print("-->前一行:"+line[-maxOffsetLength:],end="")print("-->当前行:" +preLine+b1)pass@click.command(help="""校验XML格式完整性,请使用--help查看帮助\nXmlValidator --path XML路径""")
@click.option('--path',default="",help="XML文件路径")
@click.pass_context
def parseFile(ctx,path):if(len(path) == 0):print("请输入有效XML路径!")returnparser = make_parser()handler1 = MyContentHandler()parser.setContentHandler(handler1)try:parser.parse(path)except SAXParseException as e:print("-->解析错误: ["+str(e)+"]")print("-->解析起始元素上下文-1: ",end="")printElement(handler1.elementName,handler1.isElementStart,handler1.elementAttrs,handler1.elementConent)readFileLineColumnContext(path,e.getLineNumber(),e.getColumnNumber(),20)def test():returnif __name__ == "__main__":print("Begin Parse!")parseFile(obj={})  print("End Parse!")pass

error.xml

<html>国<div>中国的xxxxx</div><div>x国内国内国内国内国内x国内国内xx</div><p>asdfasdfa国内的.sdfasfa</html>

使用和输出

python XmlValidator.py --path error.xml-->解析错误: [..\tests\resources\error.xml:5:6: mismatched tag]
-->解析起始元素上下文-1: [<p>    ]
-->前一行:sdfasdfa国内的.sdfasfa
-->当前行:    </html>

下载

  1. 使用pyinstaller编译出的独立的EXE程序。AutomaticPython

参考

python检查xml格式正确性

no-module-named-when-using-pyinstaller

[Python]_[初级]_[校验XML文件完整性]相关推荐

  1. java dom xml 换行,dom4j解析xml文件_用DOM解析XML文件,怎么才能让解析出来的文本不用换行_dom解析xml文件...

    网友求助:dom4j解析xml文件_用DOM解析XML文件,怎么才能让解析出来的文本不用换行_dom解析xml文件 问题importjava.text.SimpleDateFormat; import ...

  2. java xsd校验xml文件

    1.需要maven依赖,版本的话根据自己需求来定 <dependency><groupId>dom4j</groupId><artifactId>dom ...

  3. 【Python】识别.yaml/.ini/.xml文件

    文章目录 一.[Python]识别.yaml/.ini/.xml文件: 1.1.模块的安装: 1.2..yaml文件读取: 1.3.yaml文件写入: 1.4.yaml文件更新操作: 1.5..ini ...

  4. dom4j工具类_基于DOM4J的XML文件解析类

    XML文件解析分四类方式:DOM解析:SAX解析:JDOM解析:DOM4J解析.其中前两种属于基础方法,是官方提供的平台无关的解析方式:后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于ja ...

  5. java sax读写xml文件_使用SAXReader读取xml文件

    搜索热词 原XML文件: 99999 5275 0 001 9999 20151221 018888 0100010 5275 6600 99898989 000 c1aaaax QD00112210 ...

  6. java jdom 读取xml文件_使用Jdom读取XML文件方法

    使用Jdom读取XML文件方法,学习Spring时,我们经常看到很多xml配置文件,Spring通过在配置文件中的配置,使用IOC(控制反转),从而实现代码的灵活性,本篇我就为大家介绍一种解析xml方 ...

  7. 「Python」 ElementTree模块解析xml文件,建议小白阅读全文

    背景 Python有三种方法解析xml:SAX,DOM,Elementree.本文记录ElementTree方法解析xml. 目前自己用的是Python3.6,但在该版本中并没有xml的缩进函数ET. ...

  8. 【Python】计算VOC格式XML文件中目标面积和长宽比并生成直方图

    1.Introduction 最近目标检测的精度上不去,看看别人的文章,发现可以针对anchor进行参数优化,RPN网络生成的anchor数量与种类很大程度上影响着检测精度,anchor与检测目标越接 ...

  9. 使用python解析Wordpress导出的xml文件

    在用wordpress导出日志时,得到的往往是xml文件,具体形式如下: <?xml version="1.0" encoding="UTF-8"?> ...

最新文章

  1. C语言hk,C语言再学习
  2. 《solidity学习笔记》chapter 3-solidity其他知识
  3. 数字电路技术可能出现的简答题_技术货:模拟电路和数字电路PCB设计的区别
  4. JS获取并操作iframe中元素的方法
  5. C++之指针探究(十二):指针、下标、数组及其作函数参数
  6. Win10右键新建中没有新建文件夹,电脑右键新建文件夹不见了
  7. rtmp推流工具_EV录屏推流抖音直播教程——墨涩网
  8. 客快物流大数据项目(一):物流项目介绍和内容大纲
  9. 4600万台销量!树莓派炼成之路
  10. 新手必看:PS修图的基本步骤
  11. 计算机白板培训心得,电子白板培训心得体会
  12. 【Linux / 数据库】项目实战:tpshop项目在Linux系统环境搭建
  13. 辞职信:写给我的“藤野先生”
  14. 《SolidWorks 2014中文版完全自学手册》——1.4 SolidWorks工作环境设置
  15. MySQL 索引介绍!
  16. Unity3D——学习分享(一) 游戏开发
  17. 三十行代码实现打开笔记本摄像头进行实时口罩识别
  18. 【MySQL】数据库的约束
  19. 第十二章 SQL聚合函数 VARIANCE, VAR_SAMP, VAR_POP
  20. 地牢猎手2 Android,地牢猎手2高清版 Dungeon Hunter 2 HD

热门文章

  1. 优化策略(五)Skip-connections
  2. 如何在windows子系统中安装Quantum Espresso7.0【linux小白一只,艰辛摸索,留此纪录,如有漏洞,还请见谅】
  3. 【自制yum仓库一】自定义RPM包
  4. 跨境seo引流的13种方法
  5. Oracle批量执行脚本文件
  6. 黄金价格虽维持稳定不过上涨受阻
  7. 面趣 | 苹果最刁钻的20个面试题,试试你会通关吗?
  8. TreeMap的使用
  9. junit常用注解详细说明
  10. 百度希壤与奇安信联手打造国内首个元宇宙网络安全大会