如何根据父标记中的给定属性获取文件名和路径

时间:2016-10-24 23:18:29

标签: python xml

我想更改以下代码,只有当父标记中存在file_names属性时才会获得file_pathsfastboot="true",我提供了当前输出和预期输出,任何人都可以提供关于如何做的指导?

import sys
import os
import string
from xml.dom import minidom

if __name__ == '__main__':
    meta_contents = minidom.parse("fast.xml")
    builds_flat = meta_contents.getElementsByTagName("builds_flat")[0]
    build_nodes = builds_flat.getElementsByTagName("build")
    for build in build_nodes:
          bid_name = build.getElementsByTagName("name")[0]
          print "Checking if this is cnss related image... : \n"+bid_name.firstChild.data
          if (bid_name.firstChild.data == 'apps'):
             file_names = build.getElementsByTagName("file_name")
             file_paths = build.getElementsByTagName("file_path")
             print "now files paths...\n"
             for fn,fp in zip(file_names,file_paths):
                if (not fp.firstChild.nodeValue.endswith('/')):
                   fp.firstChild.nodeValue = fp.firstChild.nodeValue + '/'
                full_path = fp.firstChild.nodeValue+fn.firstChild.nodeValue
                print "file-to-copy: "+full_path
             break

INPUT XML: -

  <builds_flat>
    <build>
      <name>apps</name>
      <file_ref ignore="true" minimized="true">
        <file_name>adb.exe</file_name>
        <file_path>LINUX/android/vendor/qcom/proprietary/usb/host/windows/prebuilt/</file_path>
      </file_ref>
      <file_ref ignore="true" minimized="true">
        <file_name>system.img</file_name>
        <file_path>LINUX/android/out/target/product/msmcobalt/secondary-boot/</file_path>
      </file_ref>
      <download_file cmm_file_var="APPS_BINARY" fastboot_rumi="boot" fastboot="true" minimized="true">
        <file_name>boot.img</file_name>
        <file_path>LINUX/android/out/target/product/msmcobalt/</file_path>
      </download_file>
      <download_file sparse_image_path="true" fastboot_rumi="abl" fastboot="true" minimized="true">
        <file_name>abl.elf</file_name>
        <file_path>LINUX/android/out/target/product/msmcobalt/</file_path>
      </download_file>      
    </build>
  </builds_flat>

输出: -

...............
now files paths...

file-to-copy: LINUX/android/vendor/qcom/proprietary/usb/host/windows/prebuilt/adb.exe
file-to-copy: LINUX/android/out/target/product/msmcobalt/secondary-boot/system.img
file-to-copy: LINUX/android/out/target/product/msmcobalt/boot.img
file-to-copy: LINUX/android/out/target/product/msmcobalt/abl.elf

预期: -

now files paths...

........
file-to-copy: LINUX/android/out/target/product/msmcobalt/boot.img
file-to-copy: LINUX/android/out/target/product/msmcobalt/abl.elf

1 个答案:

答案 0 :(得分:1)

我想到的是一些相当快速和肮脏的事情,即只有download_file元素具有fastboot属性,对吧?如果是这种情况,您可以随时获取download_file类型的子项并过滤那些fastboot属性不是"true"的子项:

import os
from xml.dom import minidom

if __name__ == '__main__':
    meta_contents = minidom.parse("fast.xml")
    for elem in meta_contents.getElementsByTagName('download_file'):
        if elem.getAttribute('fastboot') == "true":
            path = elem.getElementsByTagName('file_path')[0].firstChild.nodeValue
            file_name = elem.getElementsByTagName('file_name')[0].firstChild.nodeValue
            print os.path.join(path, file_name)

使用您提供的样本输出:

$ python ./stack_034.py
LINUX/android/out/target/product/msmcobalt/boot.img
LINUX/android/out/target/product/msmcobalt/abl.elf

毋庸置疑......因为没有.xsd文件(也不是minidom的问题),你只能得到字符串(没有类型安全),这只适用于示例中显示的结构(您可能希望在那里添加一些额外的检查,这就是我的意思)

修改 根据这个答案中的评论:

要获取<build>中包含值<name>的{​​{1}}属性的元素,您可以:找到apps标记(值为字符串的标记) <name>),然后移动到父节点(将使您进入apps元素),然后按上述步骤继续:

build