0

以下に示すように、同様のタグの値を取得し、出力を1つのタグとして取得しようとしています。

xml 入力:

<root>
    <data>
        <slide name="file.xml">
             <subtitle>Text1</subtitle> 
             <MainTitle>Text2</MainTitle> 
             <MainTitle>text3</MainTitle> 
         </slide>
        <slide name="file.xml">
             <Title>String1</Title> 
             <Title>String2</Title> 
             <Title>String3</Title> 
             <Title>String4</Title> 
             <Title>String5</Title> 
             <Title>String6</Title> 
             <Title>String7</Title> 
             <Title>String8</Title> 
         </slide>
     </data>
 </root>

期待される出力:

<root>
    <data>
        <slide name="file.xml">
             <subtitle>Text1</subtitle> 
             <MainTitle>Text2</MainTitle> 
             <MainTitle>text3</MainTitle> 
         </slide>
        <slide name="file.xml">
             <Title>String</Title>
        </slide>
     </data>
 </root>

どんな助けでも本当にありがたいです。ありがとうございました!!

4

1 に答える 1

0

共通タグを再帰的にグループ化する必要があります。これは、テキストをどうするかを決定する関数を渡すことを可能にする実装です:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import itertools
import operator
import os.path

from lxml import etree


text = """
<root>
    <data>
        <slide name="file.xml">
             <subtitle>Text1</subtitle> 
             <MainTitle>Text2</MainTitle> 
             <MainTitle>text3</MainTitle> 
         </slide>
        <slide name="file.xml">
             <Title>String1</Title> 
             <Title>String2</Title> 
             <Title>String3</Title> 
             <Title>String4</Title> 
             <Title>String5</Title> 
             <Title>String6</Title> 
             <Title>String7</Title> 
             <Title>String8</Title> 
        </slide>
    </data>
</root>
"""


def combine_elements(elements, combine_text=', '.join):
    result = []
    for key, group in itertools.groupby(elements, operator.attrgetter('tag')):
        items = list(group)
        first_item = items[0]
        # combine only if item don't have children
        if len(items) > 1 and not len(first_item):
            combined = combine_text([el.text for el in items])
            # and if combine_text returned something, e.g. strings have 
            # common prefix
            if combined:
                first_item.text = combined
                result.append(first_item)
                continue
        result.extend(items)
    elements[:] = result
    # recursively combine others
    for element in elements:
        combine_elements(element, combine_text)


doc = etree.fromstring(text)
combine_elements(doc, os.path.commonprefix)
print etree.tostring(doc)

テキストコンバイナーとして使用os.path.commonprefix()すると、次の結果が得られます。

<root>
    <data>
        <slide name="file.xml">
             <subtitle>Text1</subtitle> 
             <MainTitle>Text2</MainTitle> 
             <MainTitle>text3</MainTitle> 
         </slide>
        <slide name="file.xml">
             <Title>String</Title> 
             </slide>
    </data>
</root>

たとえば、すべてのテキストをスラッシュで結合したい場合/は、次を使用できます。

doc = etree.fromstring(text)
combine_elements(doc, ' / '.join)

結果:

<root>
    <data>
        <slide name="file.xml">
             <subtitle>Text1</subtitle> 
             <MainTitle>Text2 / text3</MainTitle> 
             </slide>
        <slide name="file.xml">
             <Title>String1 / String2 / String3 / String4 / String5 / String6 / String7 / String8</Title> 
             </slide>
    </data>
</root>
于 2013-05-01T12:03:05.317 に答える