【问题标题】:Python - lxml delete some xml tags and move othersPython - lxml 删除一些 xml 标签并移动其他标签
【发布时间】:2013-06-01 10:05:39
【问题描述】:

我正在尝试打开一个 xml,删除整个标签及其内容,并在 xml 中移动其他标签。

这是我原来的导入 xml:

<?xml version="1.0" encoding="UTF-8"?>
<package>
    <language>en-GB</language>
    <video>
        <original_spoken_locale>en-US</original_spoken_locale>
        <copyright_cline>2012 copyright</copyright_cline>
        <release_date>2012-04-23</release_date>
        <title>Amazing Film</title>
    </video>
    <provider>testprovider</provider>
</package>

我需要删除&lt;copyright_cline&gt; 标签和&lt;title&gt; 标签。然后我需要将&lt;provider&gt; 标记向上移动到&lt;video&gt; 标记中,并将其定位在&lt;original_spoken_locale&gt; 标记下方,并将&lt;release_date&gt; 标记向下移动到&lt;video&gt; 标记下方。

这是导出的 xml:

<?xml version="1.0" encoding="UTF-8"?>
<package>
    <language>en-GB</language>
    <video>
        <original_spoken_locale>en-US</original_spoken_locale>
        <provider>testprovider</provider>
        <release_date>2012-04-23</release_date>
    </video>
    <release_date>2012-04-23</release_date>
</package>

我现在已经成功安装了 lxml,因此正在寻找一个理想的解决方案。

亲切的问候。


我已经能够删除不需要的标签及其内容,但仍然需要能够重新排序/移动其他标签,最好不要替换。我也无法删除这行 xml 代码”

<!--Carpet ID: fd54678-->

这是我目前拥有的:

from lxml import etree

xmlFileIn = '/xmls/metadata.xml'
xmlFileOut = '/xmls/output.xml'

tree = etree.parse(xmlFileIn)
root = tree.getroot()

etree.strip_elements(root, 'assets')
etree.strip_tags(root, 'assets')

etree.strip_elements(root, 'chapters')
etree.strip_tags(root, 'chapters')

etree.strip_elements(root, 'xid')
etree.strip_tags(root, 'xid')

# Write the new xml file
tree.write(xmlFileOut, pretty_print=True, xml_declaration=True, encoding="utf-8")

所以我仍然需要删除&lt;!--Carpet ID: fd54678--&gt; 标签。我想通过通配符删除这些,因为有很多&lt;!--.*--&gt;,因为中间的内容会改变。我还需要知道如何移动标签块。

【问题讨论】:

    标签: xml tags lxml


    【解决方案1】:

    既然还没有人回答,那我试试;但我来自阅读而不是实验。如果我遗漏了什么,请提前道歉……

    如何移动元素见Move an entire element in with lxml.etree

    如上所述,要特别小心,因为文本节点在 lxml 中是 not 节点(见下文)。

    至于 cmets,我在 lxml 中找不到任何获取 cmets 或直接“移动”元素的方法。你可以先用 'sed' 或其他东西剥离它们。

    注意事项

    Elementtree 因此 lxml 似乎热衷于只有一种节点。这会产生一些可能有问题的后果(“事情应该尽可能简单,但不能更简单”):

    • 使用 cmets(如本例)或 PI 更难,因为它们不是模型中的一流概念。

    • 文本尤其困难,因为 lxml 和 elementtree 使文本跟随任何 XML 元素的结束标记,成为该元素的属性(“尾部文本”)。它被视为与该元素的类型名称、属性和子元素相同。这可能有点工作(它是一个图灵机,你知道的),但它需要完全不同的思维方式。

    我注意到有关 lxml 的作者经常说它主要用于实际上没有太多文本的 XML 结构。您给出的示例似乎是这样的;如果是这样,你很幸运。但是当文字很重要时,即使是这样简单的事情:

     <p>As everyone<footnote>Well, almost everyone</footnote> knows...</p>
    

    文本“know...”是 lxml 中 节点的一部分。当您移动或删除或替换脚注时,文本会随之出现。但当然,该文本不是脚注的一部分(毕竟它发生在脚注结束之后)。

    我不知道 lxml 对“As所有人”做了什么——它不会出现在 any 元素的结尾之后。我找不到有关 lxml 如何处理它的任何信息。

    因此,如果任何地方有任何文本内容,请务必小心。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 2011-02-26
      • 1970-01-01
      相关资源
      最近更新 更多