Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-lxml重新排序xml标记_Python_Xml_Lxml - Fatal编程技术网

Python-lxml重新排序xml标记

Python-lxml重新排序xml标记,python,xml,lxml,Python,Xml,Lxml,我的xml中有一些部分需要重新排序,我知道xml不需要重新排序,但这是我需要做的,但我无法找到“正确”的方法。我正在使用lxml,并且一直在使用.insert命令重新订购。我需要对每个中的每个标签重新排序,使其看起来像这样: <asset type="preview"> <territories> <territory>SE</territory> </territories&g

我的xml中有一些部分需要重新排序,我知道xml不需要重新排序,但这是我需要做的,但我无法找到“正确”的方法。我正在使用lxml,并且一直在使用
.insert
命令重新订购。我需要对每个
中的每个标签重新排序,使其看起来像这样:

    <asset type="preview">
        <territories>
            <territory>SE</territory>
        </territories>
        <data_file role="source">
            <locale name="es"/>
            <file_name>some_name_nor-preview-sv.mov</file_name>
            <size>1715119116</size>
            <checksum type="md5">55cd94d051700be34014b2892e925fa1</checksum>
            <attribute name="crop.top">25</attribute>
            <attribute name="crop.bottom">25</attribute>
            <attribute name="crop.left">4</attribute>
            <attribute name="crop.right">4</attribute>
            <attribute name="image.burned_subtitles.locale">sv</attribute>
            <attribute name="image.textless_master">false</attribute>
        </data_file>
    </asset>

我不完全清楚你的要求。以下代码按此顺序对每个
资产\u预览
进行排序:

unknown tags
<territories>
unknown <data_file> roles
<data_file role=source>
<data_file role=notes>
理解这项技术的关键是要认识到节点是一个列表,可以按照对任何列表重新排序的方式对其进行重新排序。在我的例子中,我使用了带有自定义键的
sorted()

给你:

from lxml import etree

def preview_key(et):
    major_ordering = ['territories', 'data_file']
    minor_ordering = ['source', 'notes']
    try:
        major = major_ordering.index(et.tag)
    except ValueError:
        major = -1
    try:
        minor = minor_ordering.index(et.get('role', None))
    except ValueError:
        minor = -1
    return major, minor

def data_file_key(et):
    major_ordering = ['locale', 'file_name', 'size', 'checksum', 'attribute']
    minor_ordering = [
            "crop.top",
            "crop.bottom",
            "crop.left",
            "crop.right",
            "image.burned_subtitles.locale",
            "image.textless_master"]
    try:
        major = major_ordering.index(et.tag)
    except ValueError:
        major = -1
    try:
        minor = minor_ordering.index(et.get('name', None))
    except ValueError:
        minor = -1
    return major, minor



with open('input.xml') as input_file:
    parser = etree.XMLParser(remove_blank_text=True)
    tree = etree.parse(input_file, parser)
root = tree.getroot()

for preview in tree.xpath("//asset[@type='preview']"):
    preview[:] = sorted(preview, key=preview_key)

for data_file in tree.xpath("//data_file"):
    data_file[:] = sorted(data_file, key=data_file_key)

with open('output.xml', 'w') as output_file:
    output_file.write(etree.tostring(tree, pretty_print = True))

我已更新问题以包含我的当前代码。可能重复:
unknown tags
<territories>
unknown <data_file> roles
<data_file role=source>
<data_file role=notes>
unknown tags
<locale>
<file_name>
<size>
<checksum>
unknown attributes
<attribute name="crop.top">
other <attributes>, in a specific order.
from lxml import etree

def preview_key(et):
    major_ordering = ['territories', 'data_file']
    minor_ordering = ['source', 'notes']
    try:
        major = major_ordering.index(et.tag)
    except ValueError:
        major = -1
    try:
        minor = minor_ordering.index(et.get('role', None))
    except ValueError:
        minor = -1
    return major, minor

def data_file_key(et):
    major_ordering = ['locale', 'file_name', 'size', 'checksum', 'attribute']
    minor_ordering = [
            "crop.top",
            "crop.bottom",
            "crop.left",
            "crop.right",
            "image.burned_subtitles.locale",
            "image.textless_master"]
    try:
        major = major_ordering.index(et.tag)
    except ValueError:
        major = -1
    try:
        minor = minor_ordering.index(et.get('name', None))
    except ValueError:
        minor = -1
    return major, minor



with open('input.xml') as input_file:
    parser = etree.XMLParser(remove_blank_text=True)
    tree = etree.parse(input_file, parser)
root = tree.getroot()

for preview in tree.xpath("//asset[@type='preview']"):
    preview[:] = sorted(preview, key=preview_key)

for data_file in tree.xpath("//data_file"):
    data_file[:] = sorted(data_file, key=data_file_key)

with open('output.xml', 'w') as output_file:
    output_file.write(etree.tostring(tree, pretty_print = True))