将 XML 文件中的所有元素解析为 CSV,无需硬编码值

我想知道是否有一种方法可以解析下面的 XML 并获取大部分标签(包括嵌套标签)并将它们放入列和行中,而无需进行硬编码。

代码基本上就是这样做的,但它没有获取 descTemplate 标记内的嵌套元素。我想找到一种有效的解决方案来解析所有元素,包括嵌套元素,而无需硬编码(或尽可能少)。


进一步详细说明该程序的作用:例如,如果我们查看 xml 中的 eventType 标记。它创建一个名为“eventType”的列,并将其中的值放在该列下方。它解析的每个“eventType”标签都会将其放入同一列中。


在之前一个非常非常相似的问题中,tdelaney 慷慨地提供了这段代码,我还没有弄清楚如何扩展它来解决我的问题,所以我想我会再问一次 - 谢谢 tdelaney:


import csv

import lxml.etree

from lxml.etree import QName

import operator


class ExpandingTable:

    """A 2 dimensional table where columns are exapanded as new column

    types are discovered"""


    def __init__(self):

        """Create table that can expand rows and columns"""

        self.name_to_col = {}

        self.table = []

    

    def add_column(self, name):

        """Add column named `name` unless already included"""

        if name not in self.name_to_col:

            self.name_to_col[name] = len(self.name_to_col)

            for row in self.table:

                row.append('')

    

    def add_cell(self, name, value):

        """Add value to named column in the current row"""

        if value:

            self.add_column(name)

            self.table[-1][self.name_to_col[name]] = value.strip().replace("\r\n", " ")

            

    def new_row(self):

        """Create a new row and make it current"""

        self.table.append([''] * len(self.name_to_col))


    def header(self):

        """Gather discovered column names into a header list"""

        idx_1 = operator.itemgetter(1)

        return [name for name, _ in sorted(self.name_to_col.items(), key=idx_1)]


    def prepend_header(self):

        """Gather discovered column names into a header and

        prepend it to the list"""

        self.table.insert(0, self.header())

任何帮助将不胜感激。


波斯汪
浏览 92回答 1
1回答

哆啦的时光机

尝试这个。from simplified_scrapy import SimplifiedDoc, utilsdef getKeyValues(nodeCols, dic, header):    for nodeCol in nodeCols:        childCols = nodeCol.children        if childCols:            getKeyValues(childCols, dic, header)        else:            tag = nodeCol.tag            v = dic.get(tag)            if v:  # Cases with multiple values                dic[tag] = v + '|' + nodeCol.text # Splicing into 1 column                # i = 1                # while True:                #     tag = tag + str(i)                #     v = dic.get(tag)                #     if v == None:                #         dic[tag] = nodeCol.text                #         break                #     i = i + 1            else:                dic[tag] = nodeCol.text            if tag not in header:                header.append(tag)xml = utils.getFileContent('OMGroups.xml')doc = SimplifiedDoc(xml)  # create docheader = ['longName','shortName','nodeType'] # add columndicRow = []# nodes = doc.faults.children.childparentNodes = doc.faults.children.children # addfor nodes in parentNodes: # add   for node in nodes:  # logs,alarms...      if not node:         continue      family = node.parent      longName = family['longName'] # get the value      shortName = family['shortName']      nodeRows = node.children      for nodeRow in nodeRows:  # log,log...         dicCol = {'longName': longName, 'shortName': shortName, 'nodeType': nodeRow.tag}         nodeCols = nodeRow.children  # eventType,number         getKeyValues(nodeCols, dicCol, header)         dicRow.append(dicCol)# Prepare the data and store it in the csv filerows = [header]for dic in dicRow:    rows.append([dic.get(k) for k in header])utils.save2csv('test.csv', rows, newline='')
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python