0
#!/usr/bin/env python
import os, sys, os.path
import string 

def sort_strings_file(xmlfile,typee):
    """sort all strings within given strings.xml file"""

    all_strings = {}
    orig_type=typee

    # read original file
    tree = ET.ElementTree()
    tree.parse(xmlfile)

    # iter over all strings, stick them into dictionary
    for element in list(tree.getroot()):
        all_strings[element.attrib['name']] = element.text

    # create new root element and add all strings sorted below
    newroot = ET.Element("resources")
    for key in sorted(all_strings.keys()):
        # Check for IDs
        if typee == "id":
            typee="item"

        # set main node type
        newstring = ET.SubElement(newroot, typee)

        #add id attrib
        if orig_type == "id":
            newstring.attrib['type']="id"

        # continue on
        newstring.attrib['name'] = key
        newstring.text = all_strings[key]


    # write new root element back to xml file
    newtree = ET.ElementTree(newroot)
    newtree.write(xmlfile, encoding="UTF-8")

这很好用,但是如果一个字符串以 like 开头,<b>它会严重损坏。前任

<string name="uploading_to"><b>%s</b> Odovzdávanie do</string>

变成

<string name="uploading_to" />

我查看了 xml.etree Element 类,但它似乎只有 .text 方法。我只需要一种方法将所有内容都放在 xml 标签之间。不,我无法更改输入数据。它直接来自一个准备好翻译的 Android APK,除了它必须是有效的 XML Android 代码之外,我无法预测数据是如何/什么进来的。

4

1 回答 1

1

我认为您正在寻找itertext()方法。.text只返回直接包含在元素开头的文本:

>>> test = ET.fromstring('<elem>Sometext <subelem>more text</subelem> rest</elem>')
>>> test.text
'Sometext '
>>> ''.join(test.itertext())
'Sometext more text rest'

.itertext()另一方面,迭代器让您找到元素中包含的所有文本,包括嵌套元素内部。

但是,如果您只希望文本直接包含在元素中,跳过包含的子元素,则需要每个子元素的组合.text.tail值:

>>> (test.text or '') + ''.join(child.tail for child in test.getchildren())
'Sometext  middle  rest'

如果您需要捕获包含的所有内容,那么您需要做更多的工作;捕获.text, 并将每个孩子投射到文本中ElementTree.tostring()

>>> (test.text or '') + ''.join(ET.tostring(child) for child in test.getchildren())
'Sometext <subelem>more text</subelem> middle <subelem>other text</subelem> rest'

ET.tostring()考虑元素尾部。我使用(test.text or '')是因为.text属性也可以None

您可以在函数中捕获最后一个方法:

def innerxml(elem):
    return (elem.text or '') + ''.join(ET.tostring(child) for child in elem.getchildren())
于 2013-03-06T21:34:21.113 回答