Python:如何遍历每个XML节点并基于lis打印值

2024-05-19 19:28:34 发布

您现在位置:Python中文网/ 问答频道 /正文

为了验证目的:如何逐个节点(甚至子节点)搜索整个XML,如下所示:

XML文件:

<Summary>
<Hardware_Info>
    <HardwareType>FlashDrive</HardwareType>
    <ManufacturerDetail>
            <ManufacturerCompany>Company1</ManufacturerCompany>
            <ManufacturerDate>2017-07-20T12:26:04-04:00</ManufacturerDate>
            <ModelCode>4BR6282</ModelCode>
    </ManufacturerDetail>
    <ActivationDate>2017-07-20T12:26:04-04:00</ActivationDate>
</Hardware_Info>
<DeviceConnectionInfo>
    <Device>
        <Index>0</Index>
        <Name>Laptop1</Name>
        <Status>Installed</Status>
    </Device>
    <Device>
        <Index>1</Index>
        <Name>Laptop2</Name>
        <Status>Installed</Status>
    </Device>
</DeviceConnectionInfo>
</Summary>

并根据特定表的匹配列搜索值。为了举例说明,表格如下:

表格:

^{pr2}$

在这种情况下,我将有一个列列表:

HardwareType, ManufacturerCompany, ManufacturerDate, ActivationDate, Device.Index, Name

对于我的最终结果,我希望打印表列名的值以及在xml上找到的表名的值。例如,与原始表类似(假设验证正常):

输出结果:

 HardwareType   ManufacturerCompany    ManufacturerDate             ActivationDate              Device.Index        Name
    FlashDrive      Company1               2017-07-20T12:26:04-04:00    2017-07-20T12:26:04-04:00   0                   Laptop1
    FlashDrive      Company2               2017-07-20T12:26:04-04:00    2017-07-20T12:26:04-04:00   1                   Laptop2

当前实施:

例如,我可以获得表的列名列表,但是到目前为止,我的nkowledge实现这一点的最佳方法是:

import xml.etree.ElementTree as ET
import csv

tree = ET.parse("/test.xml")
root = tree.getroot()

f = open('/test.csv', 'w')

csvwriter = csv.writer(f)

count = 0

head = ['ManufacturerCompany','ManufacturerDate',...]

csvwriter.writerow(head)

for time in root.findall('Summary'):
     row = []
     job_name = time.find('ManufacturerDetail').find('ManufacturerCompany').text
     row.append(job_name)
     job_name = time.find('ManufacturerDetail').find('ManufacturerDate').text
     row.append(job_name)
     csvwriter.writerow(row)
f.close()

但是,这个实现没有我想要的输出循环每个功能。任何关于实施的指导或建议都会很好。在

谢谢


Tags: nameindexdevicestatusjobfindsummaryrow
1条回答
网友
1楼 · 发布于 2024-05-19 19:28:34

考虑一下XSLT,这是一种特殊用途的语言,旨在将XML文件转换成其他的XML、HTML(通常以HTML著称),但也可以将文本文件(TXT/CSV)及其method="text"转换为其他XML。具体地说,走到设备节点级别,并带来祖先项。在

Python的第三方lxml模块可以运行xslt1.0脚本。然而,XSLT是可移植的,任何XSLT processor都可以运行这样的代码,包括可用的Unix(Linux/Mac)xsltproc。在

XSLT(另存为.xsl文件,一个特殊的.xml文件;&#xa;是换行实体)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="delimiter">,</xsl:param>

  <xsl:template match="/Summary">
    <xsl:text>HardwareType,ManufacturerCompany,ManufacturerDate,ActivationDate,Device.Index,Name&#xa;</xsl:text>    
    <xsl:apply-templates select="DeviceConnectionInfo"/>    
  </xsl:template>

  <xsl:template match="DeviceConnectionInfo">
    <xsl:apply-templates select="Device"/>    
  </xsl:template>

  <xsl:template match="Device">
    <xsl:value-of select="concat(ancestor::Summary/Hardware_Info/HardwareType, $delimiter,
                                 ancestor::Summary/Hardware_Info/ManufacturerDetail/ManufacturerCompany, $delimiter,
                                 ancestor::Summary/Hardware_Info/ManufacturerDetail/ManufacturerDate, $delimiter,
                                 ancestor::Summary/Hardware_Info/ActivationDate, $delimiter,
                                 Index, $delimiter,
                                 Name)"/><xsl:text>&#xa;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

Python(使用lxml)

^{pr2}$

Python(对xsltproc的一行命令调用)

from subprocess import Popen

proc = Popen(['xsltproc -o output.csv xslt_script.xsl input.xml'], 
             shell=True, cwd='/path/to/working/directory')

输出

# HardwareType  ManufacturerCompany ManufacturerDate    ActivationDate  Device.Index    Name
# FlashDrive    Company1    2017-07-20T12:26:04-04:00   2017-07-20T12:26:04-04:00   0   Laptop1
# FlashDrive    Company1    2017-07-20T12:26:04-04:00   2017-07-20T12:26:04-04:00   1   Laptop2

相关问题 更多 >