Python解析某些行的XML文件并将该行输出到Text小部件

时间:2016-08-30 18:56:16

标签: python xml python-3.x tkinter

我需要搜索某个行的Windows msinfo文件(.nfo)并将它们打印到Text小部件。我可以print(line)在文件中排队,我可以将每一行输出到Text小部件,但是一旦我尝试指定要输出的行,它就会停止工作。我假设这是因为该文件是XML,但我在python中看到的XML解析工具似乎寻找像data = blah这样的行。当我在txt编辑器中打开它时,我正在寻找的条目看起来像这样:

    <Category name="Disks">
<Data>
<Item><![CDATA[Description]]></Item>
<Value><![CDATA[Disk drive]]></Value>
</Data>
<Data>
<Item><![CDATA[Manufacturer]]></Item>
<Value><![CDATA[(Standard disk drives)]]></Value>
</Data>
<Data>
<Item><![CDATA[Model]]></Item>
<Value><![CDATA[TOSHIB  MK1652GSX SCSI Disk Device]]></Value>
</Data>
<Data>
<Item><![CDATA[Bytes/Sector]]></Item>
<Value><![CDATA[512]]></Value>
</Data>
<Data>
<Item><![CDATA[Media Loaded]]></Item>
<Value><![CDATA[Yes]]></Value>
</Data>
<Data>
<Item><![CDATA[Media Type]]></Item>
<Value><![CDATA[Fixed hard disk]]></Value>
</Data>
<Data>
<Item><![CDATA[Partitions]]></Item>
<Value><![CDATA[2]]></Value>
</Data>
<Data>
<Item><![CDATA[SCSI Bus]]></Item>
<Value><![CDATA[1]]></Value>
</Data>
<Data>
<Item><![CDATA[SCSI Logical Unit]]></Item>
<Value><![CDATA[0]]></Value>
</Data>
<Data>
<Item><![CDATA[SCSI Port]]></Item>
<Value><![CDATA[0]]></Value>
</Data>
<Data>
<Item><![CDATA[SCSI Target ID]]></Item>
<Value><![CDATA[0]]></Value>
</Data>
<Data>
<Item><![CDATA[Sectors/Track]]></Item>
<Value><![CDATA[63]]></Value>
</Data>
<Data>
<Item><![CDATA[Size]]></Item>
<Value><![CDATA[149.05 GB (160,039,272,960 bytes)]]></Value>
</Data>
<Data>
<Item><![CDATA[Total Cylinders]]></Item>
<Value><![CDATA[19,457]]></Value>
</Data>
<Data>
<Item><![CDATA[Total Sectors]]></Item>
<Value><![CDATA[312,576,705]]></Value>
</Data>
<Data>
<Item><![CDATA[Total Tracks]]></Item>
<Value><![CDATA[4,961,535]]></Value>
</Data>
<Data>
<Item><![CDATA[Tracks/Cylinder]]></Item>
<Value><![CDATA[255]]></Value>
</Data>
<Data>
<Item><![CDATA[Partition]]></Item>
<Value><![CDATA[Disk #1, Partition #0]]></Value>
</Data>
<Data>
<Item><![CDATA[Partition Size]]></Item>
<Value><![CDATA[117.19 GB (125,830,301,184 bytes)]]></Value>
</Data>
<Data>
<Item><![CDATA[Partition Starting Offset]]></Item>
<Value><![CDATA[32,256 bytes]]></Value>
</Data>
<Data>
<Item><![CDATA[Partition]]></Item>
<Value><![CDATA[Disk #1, Partition #1]]></Value>
</Data>
<Data>
<Item><![CDATA[Partition Size]]></Item>
<Value><![CDATA[31.85 GB (34,200,714,240 bytes)]]></Value>
</Data>
<Data>
<Item><![CDATA[Partition Starting Offset]]></Item>
<Value><![CDATA[125,830,333,440 bytes]]></Value>
</Data>
<Data>

我找到post询问我想要什么,但解决方案不起作用。找不到ET.parse:

import xml.etree as ET
file = 'D:\\MsInfo\\msinfo.nfo'
tree = ET.parse(file)
root = tree.getroot()

for element in root.findall('Category'):
    value = element.find('Data')
    for child in value:
        print(child.tag ,":",child.text)

使用上述内容时我得到了:

  

“C:\ Program Files(x86)\ Python35-32 \ python.exe”“D:/ MY   STUFF / Programming / Python / testing.py“Traceback(最近的电话   last):文件“D:/ MY STUFF / Programming / Python / testing.py”,第3行,in          tree = ET.parse(file)AttributeError:module'xml.etree'没有属性'parse'

     

使用退出代码1完成处理

这是我的代码片段:

try:
    u = find("msinfo.nfo", s)
    for i in u:
        cpfotxt.insert('end', i + "\n")
        cpfotxt.yview(END)
        cpfotxt.insert('end', "================================= \n")
        with open(i, "r") as f:
            r = f.readlines()
            for line in r:
                if "Model" in line:
                    cpfotxt.insert('end', line + "\n")

如果我删除if "Model" in line:,那么它会将所有内容转储到Text小部件中。

这是在Windows上正常打开时的外观:

enter image description here

关于如何从nfo / XML文件中提取我需要的行的任何建议?

此外,从xml打印行时,字体更大,双倍行距。如何使行打印方式与普通txt文件相同?

2 个答案:

答案 0 :(得分:1)

因此,您需要了解XML的结构,然后使用您正在寻找的实际标记,而不是“数据”

    item = element.find('Item') 
    print(item.tag ,":",item.text)
    value = element.find('Value') 
    print(value.tag ,":",value.text)

您的实际问题是您需要更改您使用的导入。

import xml.etree.ElementTree as ET

https://docs.python.org/2/library/xml.etree.elementtree.html

编辑,按照结构化的方式,您可以通过说

获取数据元素列表
for data in root.findall('Data'):
    item = data.find('Item') 
    print(item.tag ,":",item.text)
    value = data.find('Value') 
    print(value.tag ,":",value.text)

现在,了解如果那&#34;数据&#34;标签不在根级别,那么你需要root.find()直到你可以到达它。换句话说,如果那些&#34;数据&#34;标签包含在一些父标签中,你需要root.find(&#34;父标签&#34;),希望你得到它的要点

编辑2:查看我自己的msinfo.nfo文件,这有效:

disks = root.find(".//Category[@name='Disks']")

for disk in disks:
    item = disk.find('Item')
    print(item.tag ,":",item.text)
    value = disk.find('Value')
    print(value.tag ,":",value.text)

注意:这使用XPath语法来查找元素,该元素仅在ElementTree1.3(Python 2.7及更高版本)中可用。你也可以通过遵循XML的结构并遍历树来强制它,直到你到达磁盘。路径是系统摘要 - &gt;组件 - &gt;存储 - &gt;磁盘和磁盘下的那些数据元素,其中项目和值为子项。

答案 1 :(得分:0)

这是我的代码与你的样本数据,我知道它可以写得更好,但我认为这解决了你的问题:) 你必须找到根(xml),然后迭代它的文本!您还可以使用其他方法(如iterfind)来获得更好的解决方案

xml_file  = "<xml><Item><![CDATA[Model]]></Item><Value><![CDATA[TOSHIB  MK1652GSX SCSI Disk Device]]></Value></xml>"
from xml.etree import ElementTree
root = ElementTree.fromstring(xml_file)

start = root.itertext()

while True:
    try:
        print start.next()
    except StopIteration:
        break

这是输出:

>>>Model
>>>TOSHIB  MK1652GSX SCSI Disk Device
相关问题