Найти - Пользователи
Полная версия: Работа с xml файлом.
Начало » Python для новичков » Работа с xml файлом.
1
Olleggerr
Здравствуйте, я чайник, но решил соорудить какую нибудь полезную прогу. Суть в том что из zip контейнера .docx файла берется document.xml, потом к примеру с ним выполняются некоторые операции(вроде замены слов и т.д.), но я столкнулся с проблемой. При использовании функции str() от прочтенных строк все русские слова превращаются в подобное.
\xd0\x9d\xd0\xb5\xd0\xba\xd0\xbe\xd1\x82\xd0\xbe\xd1\x80\xd1\x8b\xd0\xb9
А при использование метода .decode() все слова в порядке, но после записи xml файла, он не читается.

z = ZipFile("Some text.docx", "r")
file = z.open("word/document.xml").read().decode()
f = open('temp/document.xml', 'w')
f.write(file)

Знающие xml подскажите!

Заранее спасибо!
J.R.
.
Olleggerr
J.R.
Можете тогда подсказать как изменить то, в какой кодировке будет записываться файл, ибо я уже совершенно потерян.
Olleggerr
Все решено, спасибо мануалам питона и J.R., нужно было всего лишь открыть файл для записи в определенной кодировке.
z = ZipFile("Some text.docx", "r")
file = z.open("word/document.xml").read().decode("utf-8")
f = open('temp/document.xml', 'w', encoding="utf-8")
f.write(file)
doza_and
1. open тоже допускает указание кодировки.
2. чтобы получилось что-то полезное надо xml назад запихать.
3. есть https://python-docx.readthedocs.org/en/latest/
4. заменить слово будет сложно. MS Word произвольно режет текст на так называемые раны. Легко может оказаться что ваше слово разорвано и в его середину напихано 10 к служебной информации.
Olleggerr
doza_and
Благодарю, но у меня немного другая цель(заменить кодовые слова тем, что приходит из интерфейса) вроде, пока тестил всё получалось, как в полной программе работать будет не знаю, но за библиотеку все равно спасибо.
doza_and
Чем раньше вы выкинете форд из своего инструментария тем вам будет легче!!!
Эта фиговина заменяет ключевые слова в виде ${name} которые находятся в вордовом документе на значения из словаря в файле данных. (точнее это ограниченая версия mako templates).
Такой ход был выбран поскольку надо было работать и с doc и с docx. И собирать ошметки слов очень накладно.
Предупреждаю - эта штука медленная.
Посмотрите внимательно - не код а море заплаток. см. первое предложение поста.
По идее не хватает предопределенных функций для вставки табличных данных.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
u"""
mako templates by win32com in winword
"""
import mako
from mako.lookup import TemplateLookup
from mako.template import Template
from mako.lexer import Lexer
import argparse
import codecs
import os
import re
import win32com.client
from win32com.client import constants as c
import time
import shutil
import yaml
def subst_doc(word,doc,reprule):
    word.Selection.HomeKey(c.wdStory)
    fnd= word.Selection.Find
    fnd.ClearFormatting()
    fnd.Forward = True
    fnd.Format = False
    fnd.MatchCase = False
    fnd.MatchWholeWord = False
    fnd.MatchWildcards = False
    fnd.MatchSoundsLike = False
    fnd.MatchAllWordForms = False
    for a,b in reprule:
        fnd.Text = a.replace(u"\n",u"\r")
        fnd.Execute()
        e=word.Selection.End
        word.Selection.InsertAfter(b.replace(u"\n",u"\r"))
        e1=word.Selection.End
        word.Selection.End=e
        word.Selection.Cut()
#        word.Selection.Collapse(c.wdCollapseEnd)
#in_file = u"ref.docx"
#out_file = u"ref1.docx"
#data_file = u"data.yaml"
def convert(in_file, out_file, data_file,show_word=0):
    if data_file:
        with codecs.open(data_file,"r",encoding='utf-8') as f:
            data =yaml.load(f)
    else:
        data={}
    if in_file!=out_file:
        if os.path.exists(out_file):
            os.remove(out_file)
        shutil.copy(in_file,out_file)
    word = win32com.client.gencache.EnsureDispatch("Word.Application")
    word.Visible = show_word
    time.sleep(1)
    word.Documents.Open(os.path.abspath(out_file))
    doc = word.Documents(word.ActiveDocument())
    from win32com.client import constants as c
    try:
        text_b = doc.Content.Text.replace(u"\r",u"\n")
        lk= Lexer(text_b)
        text_a = Template(text_b).render(**data)
        res=lk.parse()
        reprule=[]# что ищем и на что заменяем
        i0_b=0
        i0_a=0
        expr_beg_b=0
        expr_beg_a=0
        expr_end_b=0
        expr_end_a=0
        control_count=0
        for i in res.nodes:
            if type(i) is mako.parsetree.Text:
                ct=i.content
                # нашли блок текста
                pos_b=text_b[i0_b:].find(ct)
                pos_a=text_a[i0_a:].find(ct)
                pos_b+=i0_b
                pos_a+=i0_a
                # если мы не внутри циклов то это конец предыдущего выражения
                if control_count==0:
                    expr_end_b=pos_b
                    expr_end_a=pos_a
                    # если есть конец то сбрасываем выражения в список
                    if expr_end_b>expr_beg_b:
                        reprule.append([text_b[expr_beg_b:expr_end_b],text_a[expr_beg_a:expr_end_a]])
                # передвинули стартовую позицию на конец текста
                i0_b=pos_b+len(ct)
                i0_a=pos_a+len(ct)
                if control_count==0:
                    # ставим начало на конец найденного текста
                    expr_beg_b=i0_b
                    expr_beg_a=i0_a
            else:
                # тут контролирем только вложенность for и if
                if type(i) is mako.parsetree.ControlLine:
                    if i.isend:
                        control_count-=1
                    else:
                        control_count+=1
            # если последним был шаблон то добразываем и его
            if not type(res.nodes[-1]) is mako.parsetree.Text:
                reprule.append([text_b[expr_beg_b:],text_a[expr_beg_a:]])
        subst_doc(word,doc,reprule)
        doc.Save()
    finally:
        word.Quit()
if __name__ == '__main__':
    parser = argparse.ArgumentParser(prog="word_mako",description="substitute data to word_mako infile outfile")
    parser.add_argument("-d","--data",default="",help=u"dile with data")
    parser.add_argument("-o","--output", help=u"output file")
    parser.add_argument("-w","--word", action='store_true', help=u"output file")
    parser.add_argument("file",help=u"input file")
    args = parser.parse_args()
    convert(args.file, args.output, args.data, show_word=args.word)

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB