我如何在 python 中正确解析 xml 评论

How do i parse a xml comment properly in python

我最近一直在使用 Python,我想从给定的 xml 文件中提取信息。问题是信息存储的确实不好,格式是这样的

<Content>
   <tags>
   ....
   </tags>
<![CDATA["string1"; "string2"; ....
]]>
</Content>

我不能 post 这里的全部数据,因为它大约有 20.000 行。 我只想接收包含 ["string1"、"string2"、...] 的列表,这是我目前使用的代码:

import xml.etree.ElementTree as ET

tree = ET.parse(xmlfile)
for node in tree.iter('Content'):
    print (node.text)

但是我的输出是 none。我怎样才能收到评论数据? (同样,我正在使用 Python)

问题是你的评论好像不规范。标准评论是<!--Comment here-->这样的

这些评论可以用Beautifulsoup解析,例如:

from bs4 import BeautifulSoup, Comment

xml = """<Content>
   <tags>
   ...
   </tags>
<!--[CDATA["string1"; "string2"; ....]]-->
</Content>"""
soup = BeautifulSoup(xml)
comments = soup.findAll(text=lambda text:isinstance(text, Comment))
print(comments)

这个 returns ['[CDATA["string1"; "string2"; ....]]'] 从哪里可以很容易地进一步解析成所需的字符串。

如果您有非标准评论,我建议使用正则表达式,例如:

import re
xml = """<Content>
   <tags>
   asd
   </tags>
<![CDATA["string1"; "string2"; ....]]>
</Content>"""
for i in re.findall("<!.+>",xml):
    for j in re.findall('\".+\"', i):
        print(j)

这个returns:"string1"; "string2"

您需要创建基于 SAX 的解析器而不是基于 DOM 的解析器。尤其是像你这样大的文档。

基于 sax 的解析器要求您编写自己的数据存储控制逻辑。它比简单地将其加载到 DOM 更复杂,但速度更快,因为它是逐行加载而不是一次加载整个文档。这给了它一个优势,它可以处理像你这样带有评论的松鼠案例。

构建处理程序时,您可能希望在解析器中使用 LexicalHandler 来提取这些注释。

我会给你一个关于如何构建一个的工作示例,但我已经很久没有自己做过了。有很多关于如何在线构建基于 sax 的解析器的指南,并且将把讨论推迟到另一个线程。

使用 Python 3.8 您可以在 Element TREE 中插入注释

用于读取 XML

中的属性、值、标签和注释的示例代码
import csv, sys
import xml.etree.ElementTree as ET


parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))  # Python 3.8
            tree = ET.parse(infile_path, parser)

            csvwriter.writerow(TextWorkAdapter.CSV_HEADERS)

            COMMENT = ""
            TAG =""
            NAME=""

            # Get the comment nodes
            for node in tree.iter():
                if "function Comment" in str(node.tag):
                    COMMENT = node.text
                else:
                    #read tag
                    TAG = node.tag  # string

                    #read attributes 
                    NAME= node.attrib.get("name")  # ID
                      
                    #Value
                    VALUE = node.text  # value

                    print(TAG, NAME, VALUE, COMMENT)