проблема с новыми строками при использовании toprettyxml () - PullRequest
10 голосов
/ 02 ноября 2009

В настоящее время я использую функцию toprettyxml () модуля xml.dom в скрипте Python, и у меня есть некоторые проблемы с переводом строки. Если не использовать параметр newl или если я использую toprettyxml (newl = '\ n'), на самом деле отображается несколько новых строк вместо одной.

Например

f = open(filename, 'w')
f.write(dom1.toprettyxml(encoding='UTF-8'))
f.close()

отображается:

<params>


    <param name="Level" value="#LEVEL#"/>


    <param name="Code" value="281"/>


</params>

Кто-нибудь знает, откуда возникла проблема и как я могу ее использовать? К вашему сведению, я использую Python 2.6.1

Ответы [ 7 ]

10 голосов
/ 16 марта 2010

toprettyxml() довольно ужасно. Это не вопрос Windows и '\ r \ n'. Использование любой строки в качестве параметра newl показывает, что добавляется слишком много строк. Не только это, но и другие пробелы (которые могут вызвать проблемы, когда машина читает XML).

Некоторые обходные пути доступны на
http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-and-silly-whitespace

6 голосов
/ 11 октября 2016

Я нашел другое отличное решение:

f = open(filename, 'w')
dom_string = dom1.toprettyxml(encoding='UTF-8')
dom_string = os.linesep.join([s for s in dom_string.splitlines() if s.strip()])
f.write(dom_string)
f.close()

Вышеупомянутое решение в основном удаляет нежелательные символы новой строки из строки dom_string, которые генерируются toprettyxml ().

Входные данные взяты из -> Что такое быстрая однострочная строка для удаления пустых строк из строки Python?

5 голосов
/ 22 апреля 2014

toprettyxml(newl='') у меня работает на Windows.

2 голосов
/ 31 декабря 2009

Если вы не против установки новых пакетов, попробуйте Beautifulsoup. У меня был очень хороший опыт работы с xml prettyfier .

1 голос
/ 20 сентября 2017

Это довольно старый вопрос, но я думаю, я знаю, в чем проблема:

Миниатюрная печать довольно простой метод. Он просто добавляет символы, которые вы указали в качестве аргументов. Это означает, что он будет дублировать символы, если они уже существуют.

например. если вы анализируете XML-файл, который выглядит следующим образом:

<parent>
   <child>
      Some text
   </child>
</parent>

в домике уже есть символы новой строки и отступы. Они воспринимаются минидомом как текстовые узлы и остаются там, когда вы разбираете его в объект dom.

Если вы сейчас приступите к преобразованию объекта dom в строку XML, эти текстовые узлы все еще будут там. То есть символы новой строки и вкладки отступа все еще остаются. Теперь, используя симпатичную печать, просто добавьте больше новых строк и больше вкладок. Вот почему в этом случае вообще не используется симпатичная печать или указание newl='' приведет к желаемому результату.

Однако, вы генерируете dom в своем скрипте, текстовые узлы там не будут, поэтому красивая печать с newl='\r\n' и / или addindent='\t' будет довольно симпатичной.

TL; DR Отступы и переводы строк остаются от разбора, а симпатичная печать просто добавляет больше

0 голосов
/ 11 марта 2019

Следующая функция сработала для моей проблемы. Мне пришлось использовать Python 2.7, и мне не разрешили установить какой-либо сторонний дополнительный пакет.

Суть реализации заключается в следующем:

  1. Используйте dom.toprettyxml ()
  2. Удалить все пробелы
  3. Добавьте новые строки и вкладки согласно вашему требованию.

~

import os
import re
import xml.dom.minidom
import sys

class XmlTag:
    opening = 0
    closing = 1
    self_closing = 2
    closing_tag = "</"
    self_closing_tag = "/>"
    opening_tag = "<"

def to_pretty_xml(xml_file_path):
    pretty_xml = ""
    space_or_tab_count = "  " # Add spaces or use \t
    tab_count = 0
    last_tag = -1

    dom = xml.dom.minidom.parse(xml_file_path)

    # get pretty-printed version of input file
    string_xml = dom.toprettyxml(' ', os.linesep)

    # remove version tag
    string_xml = string_xml.replace("<?xml version=\"1.0\" ?>", '')

    # remove empty lines and spaces
    string_xml = "".join(string_xml.split())

    # move each tag to new line
    string_xml = string_xml.replace('>', '>\n')

    for line in string_xml.split('\n'):
        if line.__contains__(XmlTag.closing_tag):

            # For consecutive closing tags decrease the indentation
            if last_tag == XmlTag.closing:
                tab_count = tab_count - 1

            # Move closing element to next line
            if last_tag == XmlTag.closing or last_tag == XmlTag.self_closing:
                pretty_xml = pretty_xml + '\n' + (space_or_tab_count * tab_count)

            pretty_xml = pretty_xml + line
            last_tag = XmlTag.closing

        elif line.__contains__(XmlTag.self_closing_tag):

            # Print self closing on next line with one indentation from parent node
            pretty_xml = pretty_xml + '\n' + (space_or_tab_count * (tab_count+1)) + line
            last_tag = XmlTag.self_closing

        elif line.__contains__(XmlTag.opening_tag):

            # For consecutive opening tags increase the indentation
            if last_tag == XmlTag.opening:
                tab_count = tab_count + 1

            # Move opening element to next line
            if last_tag == XmlTag.opening or last_tag == XmlTag.closing:
                pretty_xml = pretty_xml + '\n' + (space_or_tab_count * tab_count)

            pretty_xml = pretty_xml + line
            last_tag = XmlTag.opening

    return pretty_xml

pretty_xml = to_pretty_xml("simple.xml")

with open("pretty.xml", 'w') as f:
    f.write(pretty_xml)
0 голосов
/ 02 ноября 2009

Вы просматриваете полученный файл в Windows? Если это так, попробуйте использовать toprettyxml(newl='\r\n').

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...