Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 按元素将包含多条记录和无效字符的XML文件拆分为多个文本文件_Python 3.x_Xml Parsing - Fatal编程技术网

Python 3.x 按元素将包含多条记录和无效字符的XML文件拆分为多个文本文件

Python 3.x 按元素将包含多条记录和无效字符的XML文件拆分为多个文本文件,python-3.x,xml-parsing,Python 3.x,Xml Parsing,我有一组具有一致结构的100K XML ish(稍后将详细介绍)遗留文件—一个包含多个日期和数据对记录的归档包装器 我需要提取单个记录并将其写入单个文本文件,但由于非法字符和随机的CR/space/tab前导和尾随数据,我在解析数据时遇到了问题 关于XML文件 这些文件是从失效系统继承的,无法重新生成。每个文件都非常小(小于5MB) 每个数据记录都有一个日期记录: vendor-1-records.xml <Archive> <Date>10 Jan 2019</

我有一组具有一致结构的100K XML ish(稍后将详细介绍)遗留文件—一个包含多个日期和数据对记录的归档包装器

我需要提取单个记录并将其写入单个文本文件,但由于非法字符和随机的CR/space/tab前导和尾随数据,我在解析数据时遇到了问题

关于XML文件 这些文件是从失效系统继承的,无法重新生成。每个文件都非常小(小于5MB)

每个数据记录都有一个日期记录:

vendor-1-records.xml

<Archive>
<Date>10 Jan 2019</Date>
<Data>Vendor 1 Record 1</Data>
<Date>12 Jan 2019</Date>
<Data>Vendor 1 Record 2</Data>
(etc)
</Archive>

vendor-2-records.xml

<Archive>
<Date>22 September 2019</Date>
<Data>Vendor 2 Record 1</Data>
<Date>24 September 2019</Date>
<Data>Vendor 2 Record 2</Data>
(etc)
</Archive>

...

vendor-100000-records.xml
<Archive>
<Date>12 April 2019</Date>
<Data>Vendor 100000 Record 1</Data>
<Date>24 October 2019</Date>
<Data>Vendor 100000 Record 2</Data>
(etc)
</Archive>


问题1:XML数据记录中的非法字符 一个问题是,元素包含多个XML库(如Etree/etc)终止的字符,包括控制字符、格式字符和各种Alt+XXX类型的字符

我在网上搜索过,找到了各种各样的变通方法和regex,以及搜索和替换脚本,但在Python中唯一有效的是lxml的etree,recover=True

但是,这并不总是有效的,因为有些文件显然不是UTF-8,所以我得到了错误:

lxml.etree.XMLSyntaxError: Input is not proper UTF-8, indicate encoding !
问题2-数据记录具有随机数量的前导和后继CR和空格 对于我可以用lxml.etree解析的文件,实际数据记录也包装在CRs和随机空间中:

<Data>
(random numbers of CR + spaces and sometimes tabs)
*content<CR>*
(random numbers of CR + spaces and sometimes tabs)
</Data>
我得到一组空数据标记(文件中的每个数据记录对应一个),如

问题
  • 有没有比Python的lxml更有效的语言/模块来忽略非法字符?正如我所说的,我已经翻阅了许多烹饪书博客文章、SE文章等来预处理XML,但似乎没有任何东西真正起作用——总是有一个控制字符/etc挂起解析器
  • SE建议发布一篇关于清理引用旧Atlassian工具()的XML的帖子。我做了一些基本的测试,它似乎可以工作,但开放的其他建议

  • 我没有在Python中使用过太多正则表达式-关于如何处理清理数据标记中的前导/尾随CR/空格/制表符随机性,有什么建议吗?我想要在该数据标记中的实际记录字符串的末尾也有一个CR,并且可能还包含制表符,所以我不能只是搜索和替换。也许有一种正则表达式的方法可以做到这一点,但是我的正则表达式很弱

  • 对于我的问题1和2,我解决了我自己的问题:

    • 问题1(解析和无效字符)
      • 我使用批处理脚本通过()中引用的Atlassian jar运行了整个文件集:
    该实用工具标准化了所有XML文件,并使它们可以通过lxml解析

    • 问题2(数据元素内的CR、空格、选项卡)
      • lxml的此配置去除了所有空白,并处理了无效字符问题
    通过这两个步骤,我现在可以开始提取记录并将其写入各个文件:

    # for each date, finding the next item gives me the Data element and I can strip the tab/CR/whitespace:
    for item in tree.findall('Date'):
            dt = parse_datestamp(item.text.strip())
            content = item.getnext().text.strip()
    

    在这里,作为文本进行解析,也许之后作为XML进行解析是有意义的。例如您提到的atlassion XML清理器。或者拥有自己的代码,这样您就可以逐步解决编码错误、非法字符、空白等问题。
        parser = etree.XMLParser(recover=True)
        tree = etree.parse('vendor-1-records.xml', parser=parser)
        tags_needed = tree.iter('Data')
        for it in tags_needed:
            print (it.tag,it.attrib)
    
    Data {}
    Data {}
    
    for %%f in (*.xml) do (
        java -jar atlassian-xml-cleaner-0.1.jar %%f >  clean\%%~f
    )
    
    
    from lxml import etree
        parser = etree.XMLParser(encoding = 'utf-8',recover=True,remove_blank_text=True)
        tree = etree.parse(filepath, parser=parser)
    
    # for each date, finding the next item gives me the Data element and I can strip the tab/CR/whitespace:
    for item in tree.findall('Date'):
            dt = parse_datestamp(item.text.strip())
            content = item.getnext().text.strip()