programing

파이썬의 요소를 얻으려면 어떻게 해야 합니까?XML 파일에 인쇄할 트리?

mailnote 2023. 10. 3. 11:15
반응형

파이썬의 요소를 얻으려면 어떻게 해야 합니까?XML 파일에 인쇄할 트리?

배경

SQLite를 사용하여 데이터베이스에 접속하여 원하는 정보를 검색하고 있습니다.Element를 사용하고 있습니다.Python 버전 2.6에서 트리를 사용하여 해당 정보로 XML 파일을 만듭니다.

코드

import sqlite3
import xml.etree.ElementTree as ET

# NOTE: Omitted code where I acccess the database,
# pull data, and add elements to the tree

tree = ET.ElementTree(root)

# Pretty printing to Python shell for testing purposes
from xml.dom import minidom
print minidom.parseString(ET.tostring(root)).toprettyxml(indent = "   ")

#######  Here lies my problem  #######
tree.write("New_Database.xml")

시도

사용해 보았습니다.tree.write("New_Database.xml", "utf-8")위의 코드 마지막 줄 대신 XML의 레이아웃을 편집하지 않았습니다. 여전히 엉망진창입니다.

저는 또한 빈둥거리기로 결정하고 다음과 같이 노력했습니다.
tree = minidom.parseString(ET.tostring(root)).toprettyxml(indent = " ")
Python 셸에 인쇄하는 대신 AttributeError: 'unicode' 개체에 'write' 속성이 없습니다.

문의사항

마지막 줄에 있는 XML 파일에 트리를 쓸 때 Python 셸처럼 XML 파일에 인쇄할 수 있는 방법이 있습니까?

사용해도 됩니까?toprettyxml()이것을 할 수 있는 다른 방법이 있습니까?

XML 문자열이 무엇이든 파일에 문자열을 쓰고 쓰기 위한 파일을 열어서 원하는 파일에 쓸 수 있습니다.

from xml.dom import minidom

xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent="   ")
with open("New_Database.xml", "w") as f:
    f.write(xmlstr)

특히 파이썬 2에서는 문자열의 유니코드 문자에 대해 덜 엄격하고 덜 복잡한 한 가지 가능성이 있습니다.당신의toprettyxmlmethod handsback(유니코드 문자열).u"something"), 그런 다음 UTF-8과 같은 적합한 파일 인코딩에 캐스트할 수 있습니다. 예를 들어 한 쓰기 라인을 다음과 같이 대체합니다.

f.write(xmlstr.encode('utf-8'))

단순히 다음과 같은 기능으로 해결했습니다.

xml.etree.ElementTree.indent(tree, space=" ", level=0)하위 트리에 공백을 추가하여 트리를 시각적으로 들여씁니다.이를 통해 예쁜 인쇄 XML 출력을 생성할 수 있습니다.나무가 될 수 있습니다.Element아니면ElementTree.space은 각 들여쓰기 수준에 대해 삽입될 공백 문자열이며, 기본적으로 두 개의 공백 문자가 있습니다.이미 들여쓰기된 트리 내부의 부분 하위 트리를 들여쓰기하려면 초기 들여쓰기 수준을 다음과 같이 전달합니다.level.

tree = ET.ElementTree(root)
ET.indent(tree, space="\t", level=0)
tree.write(file_name, encoding="utf-8")

참고, 그indent()함수는 파이썬 3.9에 추가되었습니다.

스트레이트 엘레먼트를 사용하는 방법을 찾았습니다.나무, 하지만 그것은 다소 복잡합니다.

ElementTree에는 예를 들어 요소의 텍스트와 꼬리를 편집하는 기능이 있습니다.element.text="text"그리고.element.tail="tail". 이것들을 특정한 방법으로 사용해야 물건들이 줄을 설 수 있기 때문에 탈출 캐릭터를 알아야 합니다.

기본적인 예로는 다음과 같습니다.

저는 다음 파일을 가지고 있습니다.

<?xml version='1.0' encoding='utf-8'?>
<root>
    <data version="1">
        <data>76939</data>
    </data>
    <data version="2">
        <data>266720</data>
        <newdata>3569</newdata>
    </data>
</root>

세 번째 요소를 넣고 예쁘게 유지하려면 다음 코드가 필요합니다.

addElement = ET.Element("data")             # Make a new element
addElement.set("version", "3")              # Set the element's attribute
addElement.tail = "\n"                      # Edit the element's tail
addElement.text = "\n\t\t"                  # Edit the element's text
newData = ET.SubElement(addElement, "data") # Make a subelement and attach it to our element
newData.tail = "\n\t"                       # Edit the subelement's tail
newData.text = "5431"                       # Edit the subelement's text
root[-1].tail = "\n\t"                      # Edit the previous element's tail, so that our new element is properly placed
root.append(addElement)                     # Add the element to the tree.

내부 데이터 태그와 같이 내부 태그를 들여쓰려면 상위 요소의 텍스트에 추가해야 합니다.요소 뒤에 들여쓰기를 원하는 경우(일반적으로 하위 요소 뒤에) 꼬리에 넣습니다.

이 코드는 파일에 쓸 때 다음과 같은 결과를 제공합니다.

<?xml version='1.0' encoding='utf-8'?>
<root>
    <data version="1">
        <data>76939</data>
    </data>
    <data version="2">
        <data>266720</data>
        <newdata>3569</newdata>
    </data> <!--root[-1].tail-->
    <data version="3"> <!--addElement's text-->
        <data>5431</data> <!--newData's tail-->
    </data> <!--addElement's tail-->
</root>

또 이 일률적으로 를 , ,\t 수 .\t.

이 코드는 Python 3.7에서 만들어졌지만 Python 2.7에서는 여전히 작동합니다.

Ben Anderson의 답변을 함수로 리핑합니다.

def _pretty_print(current, parent=None, index=-1, depth=0):
    for i, node in enumerate(current):
        _pretty_print(node, current, i, depth + 1)
    if parent is not None:
        if index == 0:
            parent.text = '\n' + ('\t' * depth)
        else:
            parent[index - 1].tail = '\n' + ('\t' * depth)
        if index == len(parent) - 1:
            current.tail = '\n' + ('\t' * (depth - 1))

그래서 예쁜 데이터에 대한 테스트를 실행합니다.

import xml.etree.ElementTree as ET
root = ET.fromstring('''<?xml version='1.0' encoding='utf-8'?>
<root>
    <data version="1"><data>76939</data>
</data><data version="2">
        <data>266720</data><newdata>3569</newdata>
    </data> <!--root[-1].tail-->
    <data version="3"> <!--addElement's text-->
<data>5431</data> <!--newData's tail-->
    </data> <!--addElement's tail-->
</root>
''')
_pretty_print(root)

tree = ET.ElementTree(root)
tree.write("pretty.xml")
with open("pretty.xml", 'r') as f:
    print(f.read())

다음을 확인합니다.

<root>
    <data version="1">
        <data>76939</data>
    </data>
    <data version="2">
        <data>266720</data>
        <newdata>3569</newdata>
    </data>
    <data version="3">
        <data>5431</data>
    </data>
</root>

bs4

pip install bs4

다음 코드를 사용하여 예쁜 인쇄:

from bs4 import BeautifulSoup

x = your xml

print(BeautifulSoup(x, "xml").prettify())

lxml을 사용하려면 다음과 같은 방법으로 수행할 수 있습니다.

from lxml import etree

xml_object = etree.tostring(root,
                            pretty_print=True,
                            xml_declaration=True,
                            encoding='UTF-8')

with open("xmlfile.xml", "wb") as writter:
    writter.write(xml_object)`

되는 경우(예: ).py:pytype="TREE"할 수 .xml_object

etree.cleanup_namespaces(root) 

이 정도면 코드의 적응에 충분할 것입니다.

에서 XML () (*) 1이라는 을 읽고 파싱(할 수 fname:

from xml.dom import minidom
print(minidom.parseString(open(fname).read()).toprettyxml(indent="  "))

(* 가져오기를 계산하지 않음)

라팔과 비슷합니다.Py의 솔루션이지만 입력을 수정하지 않고 XML을 형식화된 문자열로 반환합니다.

def prettyPrint(element):
    encoding = 'UTF-8'
    # Create a copy of the input element: Convert to string, then parse again
    copy = ET.fromstring(ET.tostring(element))
    # Format copy. This needs Python 3.9+
    ET.indent(copy, space="    ", level=0)
    # tostring() returns a binary, so we need to decode it to get a string
    return ET.tostring(copy, encoding=encoding).decode(encoding)

copy.write(...)오버헤드를 피하기 위해서입니다.

언급URL : https://stackoverflow.com/questions/28813876/how-do-i-get-pythons-elementtree-to-pretty-print-to-an-xml-file

반응형