2015-03-31 2 views
0

Я строки XML как следующее:Rewrite XML и сохранить контекст

xml = """ 
<body> 
    <head>1. Un livre sur <persName type="author" key="Ronsard, Pierre de (1524-1585)" ref="http://www.idref.fr/027107957">Ronsard</persName></head> 
    <head>2. <title>La pitié des églises</title> par <persName key="Barrès, Maurice (1862-1923)" ref="http://www.idref.fr/026706601" type="author">Barrès</persName></head> 
</body> 
""" 

Я некоторая функция называется processLine(line), что занимает целую строку (текст в <head> без тегов), в моем случае эти две строки будет обработаны processLine функции:

1. Un livre sur Ronsard 
2. La pitié des églises par Barrès 

и конкатенация определенной строки в некоторые слова каждой строки, например:

"Ronsard" becomes "Ronsard I-PER" 
"Barrès" becomes "Barrès I-PER" 

Вот код, который я сделал до сих пор, используя библиотеку etree Питона:

from lxml import etree 

root = etree.fromstring(xml) 
pars = root.xpath('//body//head') 

for par in pars: 
    line = par.text # return the line stripped from tags 
    processLine(line) 

Мой вопрос: Как я могу сохранить эти изменения в файле XML, без потери его структуры?

то есть: Мой новый файл XML в моем Exemple будет:

newxml = """ 
<body> 
    <head>1. Un livre sur <persName type="author" key="Ronsard, Pierre de (1524-1585)" ref="http://www.idref.fr/027107957">Ronsard I-PER</persName></head> 
    <head>2. <title>La pitié des églises</title> par <persName key="Barrès, Maurice (1862-1923)" ref="http://www.idref.fr/026706601" type="author">Barrès I-PER</persName></head> 
</body> 
""" 

ответ

1

Вы можете установить метку»text свойство, что вам нужно, а затем просто позвонить etree.tostring(rootElt, prettyPrint = True).

Да, и обратите внимание: я выбрать все <persName> теги, не все заголовки itselves:

pars = root.xpath('//body//head//persName') 

Проверить это:

from lxml import etree 

xml = """ 
<body> 
    <head>1. Un livre sur <persName type="author" key="Ronsard, Pierre de (1524-1585)" ref="http://www.idref.fr/027107957">Ronsard</persName></head> 
    <head>2. <title>La pitié des églises</title> par <persName key="Barrès, Maurice (1862-1923)" ref="http://www.idref.fr/026706601" type="author">Barrès</persName></head> 
</body> 
""" 

root = etree.fromstring(xml) 
pars = root.xpath('//body//head//persName') 

for par in pars: 
    line = par.text # return the line stripped from tags 
    processLine(line) 

    par.text = par.text + ' I-PER' 

print(etree.tostring(root, unicode = True, pretty_print = True)) 

Это печатает следующий XML:

<body> 
    <head>1. Un livre sur <persName type="author" key="Ronsard, Pierre de (1524-1585)" ref="http://www.idref.fr/027107957">Ronsard I-PER</persName></head> 
    <head>2. <title>La pitié des églises</title> par <persName key="Barrès, Maurice (1862-1923)" ref="http://www.idref.fr/026706601" type="author">Barrès I-PER</persName></head> 
</body> 

Если вы хотите обработать все заголовки и только потом имена процессов - возможно, вы хотите, чтобы t o выбрать внутренний тег (persName) из заголовка самого тега (head)?

for par in pars: 
    # ... 

    pers = par.xpath('//persName') 

    for per in pers: 
     per.text = per.text + ' I-PER' 

Этот код дает точно такой же результат, но в функции processLine вы будете по-прежнему иметь дело со всей <head> тега, в то время как pers переменная будет содержать все, что тега <persName> детей.

Смежные вопросы