파이썬을 사용하여 XML을 JSON으로 변환 하시겠습니까?
웹에서 부적절한 XML-> JSON 코드를 꽤 많이 보았고 Stack 사용자와 약간의 상호 작용을 하면서이 군중이 Google 결과의 처음 몇 페이지 이상을 도울 수 있다고 확신합니다.
따라서 날씨 피드를 파싱하고 있으며 수많은 웹 사이트에서 날씨 위젯을 채워야합니다. 우리는 지금 파이썬 기반 솔루션을 찾고 있습니다.
이 공개 weather.com RSS 피드 는 우리가 구문 분석 할 내용의 좋은 예입니다 ( 실제 weather.com 피드에는 파트너 관계로 인해 추가 정보가 포함되어 있습니다 ).
간단히 말해서 파이썬을 사용하여 XML을 JSON으로 어떻게 변환해야합니까?
XML과 JSON간에 "일대일"맵핑이 없으므로 하나를 다른 것으로 변환하려면 결과 로 수행 하려는 작업을 이해해야 합니다.
파이썬의 표준 라이브러리에는 XML (DOM, SAX 및 ElementTree 포함) 을 파싱하기위한 여러 모듈이 있습니다. Python 2.6부터 Python 데이터 구조를 JSON으로 또는 JSON으로 변환하는 기능이 json
모듈에 포함되어 있습니다.
인프라가 있습니다.
xmltodict (전체 공개 : 필자가 작성)는이 "standard"에 따라 XML을 dict + list + string 구조로 변환하는 데 도움이 됩니다. 그것은이다 국외 거주자는 그래서 매우 빨리 메모리에 전체 XML 트리를로드 할 필요가 없습니다, 기반.
해당 데이터 구조가 있으면 JSON으로 직렬화 할 수 있습니다.
import xmltodict, json
o = xmltodict.parse('<e> <a>text</a> <a>text</a> </e>')
json.dumps(o) # '{"e": {"a": ["text", "text"]}}'
xmljson 라이브러리를 사용하여 다른 XML JSON 규칙을 사용하여 변환 할 수 있습니다 .
예를 들어이 XML은 다음과 같습니다.
<p id="1">text</p>
BadgerFish 규칙 을 통해 다음과 같이 변환됩니다 .
{
'p': {
'@id': 1,
'$': 'text'
}
}
그리고 GData 규칙 을 통해 (속성은 지원되지 않습니다) :
{
'p': {
'$t': 'text'
}
}
... 그리고 Parker 규칙 을 통해 (속성은 지원되지 않습니다) :
{
'p': 'text'
}
동일한 규칙을 사용하여 XML에서 JSON으로, JSON에서 XML로 변환 할 수 있습니다.
>>> import json, xmljson
>>> from lxml.etree import fromstring, tostring
>>> xml = fromstring('<p id="1">text</p>')
>>> json.dumps(xmljson.badgerfish.data(xml))
'{"p": {"@id": 1, "$": "text"}}'
>>> xmljson.parker.etree({'ul': {'li': [1, 2]}})
# Creates [<ul><li>1</li><li>2</li></ul>]
공개 : 나는이 도서관을 썼다. 미래의 검색 자들에게 도움이되기를 바랍니다.
여기에 내가 작성한 코드가 있습니다. 내용을 파싱하지 않고 평범한 변환 만하면됩니다.
from xml.dom import minidom
import simplejson as json
def parse_element(element):
dict_data = dict()
if element.nodeType == element.TEXT_NODE:
dict_data['data'] = element.data
if element.nodeType not in [element.TEXT_NODE, element.DOCUMENT_NODE,
element.DOCUMENT_TYPE_NODE]:
for item in element.attributes.items():
dict_data[item[0]] = item[1]
if element.nodeType not in [element.TEXT_NODE, element.DOCUMENT_TYPE_NODE]:
for child in element.childNodes:
child_name, child_dict = parse_element(child)
if child_name in dict_data:
try:
dict_data[child_name].append(child_dict)
except AttributeError:
dict_data[child_name] = [dict_data[child_name], child_dict]
else:
dict_data[child_name] = child_dict
return element.nodeName, dict_data
if __name__ == '__main__':
dom = minidom.parse('data.xml')
f = open('data.json', 'w')
f.write(json.dumps(parse_element(dom), sort_keys=True, indent=4))
f.close()
XML 기반 마크 업을 JSON으로 전송하여 손실없이 원래 형식으로 다시 변환 할 수있는 방법이 있습니다. http://jsonml.org/를 참조하십시오 .
일종의 XSLT JSON입니다. 도움이 되었기를 바랍니다.
언젠가 모든 데이터 대신 응답 코드 만 얻는다면 json 구문 분석과 같은 오류가 발생 하므로 텍스트 로 변환해야 합니다
import xmltodict
data = requests.get(url)
xpars = xmltodict.parse(data.text)
json = json.dumps(xpars)
print json
http://designtheory.org/library/extrep/designdb-1.0.pdf 를 참조하십시오 . 이 프로젝트는 큰 XML 파일 라이브러리의 XML을 JSON으로 변환하는 것으로 시작합니다. 변환에 대한 많은 연구가 있었고 가장 간단한 직관적 인 XML-> JSON 매핑이 생성되었습니다 (문서의 초기에 설명되어 있음). 요약하면 모든 것을 JSON 객체로 변환하고 반복 블록을 객체 목록으로 넣습니다.
키 / 값 쌍을 의미하는 객체 (Python의 사전, Java의 해시 맵, JavaScript의 객체)
동일한 문서를 얻기 위해 XML로 다시 매핑하는 것은 없기 때문에 키 / 값 쌍이 속성인지 또는 <key>value</key>
정보 인지 알 수 없기 때문에 정보가 손실됩니다.
나에게 묻는다면, 속성은 시작하기위한 핵이다. 그런 다음 다시 HTML에서 잘 작동했습니다.
글쎄, 아마도 가장 간단한 방법은 XML을 사전으로 구문 분석 한 다음 simplejson으로 직렬화하는 것입니다.
직접 전환하지 않는 것이 좋습니다. XML을 객체로 변환 한 다음 객체에서 JSON으로 변환합니다.
제 생각에 이것은 XML과 JSON이 어떻게 대응되는지에 대한 명확한 정의를 제공합니다.
제대로 되려면 시간이 걸리고 일부를 생성하는 데 도움이되는 도구를 작성할 수도 있지만 대략 다음과 같습니다.
class Channel:
def __init__(self)
self.items = []
self.title = ""
def from_xml( self, xml_node ):
self.title = xml_node.xpath("title/text()")[0]
for x in xml_node.xpath("item"):
item = Item()
item.from_xml( x )
self.items.append( item )
def to_json( self ):
retval = {}
retval['title'] = title
retval['items'] = []
for x in items:
retval.append( x.to_json() )
return retval
class Item:
def __init__(self):
...
def from_xml( self, xml_node ):
...
def to_json( self ):
...
간단한 XML 스니핑에서 정규 표현식을 사용하면 문제를 해결할 수 있습니다. 예를 들면 다음과 같습니다.
# <user><name>Happy Man</name>...</user>
import re
names = re.findall(r'<name>(\w+)<\/name>', xml_string)
# do some thing to names
@Dan이 말했듯이 XML 파싱으로 수행하려면 데이터가 다르기 때문에 일대일 솔루션이 없습니다. 내 제안은 lxml을 사용하는 것입니다. json으로 끝나지 않았지만 lxml.objectify 는 조용한 좋은 결과를 제공합니다.
>>> from lxml import objectify
>>> root = objectify.fromstring("""
... <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
... <a attr1="foo" attr2="bar">1</a>
... <a>1.2</a>
... <b>1</b>
... <b>true</b>
... <c>what?</c>
... <d xsi:nil="true"/>
... </root>
... """)
>>> print(str(root))
root = None [ObjectifiedElement]
a = 1 [IntElement]
* attr1 = 'foo'
* attr2 = 'bar'
a = 1.2 [FloatElement]
b = 1 [IntElement]
b = True [BoolElement]
c = 'what?' [StringElement]
d = None [NoneElement]
* xsi:nil = 'true'
XML 파싱을위한 내장 라이브러리는 꽤 좋지만 lxml 부분 입니다.
그러나 RSS 피드 를 파싱하려면 Atom을 파싱 할 수있는 Universal Feed Parser를 권장 합니다. 주요 이점은 대부분의 기형 사료를 소화 할 수 있다는 것입니다.
Python 2.6에는 이미 JSON 파서가 포함되어 있지만 속도 가 향상된 최신 버전을 simplejson 으로 사용할 수 있습니다 .
이러한 도구를 사용하면 앱을 만드는 것이 그렇게 어렵지 않아야합니다.
파이썬에서 XML로 무엇이든 할 때는 거의 항상 lxml 패키지를 사용합니다. 나는 대부분의 사람들이 lxml을 사용한다고 생각합니다. xmltodict를 사용할 수는 있지만 XML 구문 분석에 대한 벌금을 다시 지불해야합니다.
lxml을 사용하여 XML을 json으로 변환하려면 다음을 수행하십시오.
- lxml을 사용하여 XML 문서 구문 분석
- lxml을 dict로 변환
- 목록을 json으로 변환
내 프로젝트에서 다음 클래스를 사용합니다. toJson 방법을 사용하십시오.
from lxml import etree
import json
class Element:
'''
Wrapper on the etree.Element class. Extends functionality to output element
as a dictionary.
'''
def __init__(self, element):
'''
:param: element a normal etree.Element instance
'''
self.element = element
def toDict(self):
'''
Returns the element as a dictionary. This includes all child elements.
'''
rval = {
self.element.tag: {
'attributes': dict(self.element.items()),
},
}
for child in self.element:
rval[self.element.tag].update(Element(child).toDict())
return rval
class XmlDocument:
'''
Wraps lxml to provide:
- cleaner access to some common lxml.etree functions
- converter from XML to dict
- converter from XML to json
'''
def __init__(self, xml = '<empty/>', filename=None):
'''
There are two ways to initialize the XmlDocument contents:
- String
- File
You don't have to initialize the XmlDocument during instantiation
though. You can do it later with the 'set' method. If you choose to
initialize later XmlDocument will be initialized with "<empty/>".
:param: xml Set this argument if you want to parse from a string.
:param: filename Set this argument if you want to parse from a file.
'''
self.set(xml, filename)
def set(self, xml=None, filename=None):
'''
Use this to set or reset the contents of the XmlDocument.
:param: xml Set this argument if you want to parse from a string.
:param: filename Set this argument if you want to parse from a file.
'''
if filename is not None:
self.tree = etree.parse(filename)
self.root = self.tree.getroot()
else:
self.root = etree.fromstring(xml)
self.tree = etree.ElementTree(self.root)
def dump(self):
etree.dump(self.root)
def getXml(self):
'''
return document as a string
'''
return etree.tostring(self.root)
def xpath(self, xpath):
'''
Return elements that match the given xpath.
:param: xpath
'''
return self.tree.xpath(xpath);
def nodes(self):
'''
Return all elements
'''
return self.root.iter('*')
def toDict(self):
'''
Convert to a python dictionary
'''
return Element(self.root).toDict()
def toJson(self, indent=None):
'''
Convert to JSON
'''
return json.dumps(self.toDict(), indent=indent)
if __name__ == "__main__":
xml='''<system>
<product>
<demod>
<frequency value='2.215' units='MHz'>
<blah value='1'/>
</frequency>
</demod>
</product>
</system>
'''
doc = XmlDocument(xml)
print doc.toJson(indent=4)
내장 메인 의 출력 은 다음과 같습니다.
{
"system": {
"attributes": {},
"product": {
"attributes": {},
"demod": {
"attributes": {},
"frequency": {
"attributes": {
"units": "MHz",
"value": "2.215"
},
"blah": {
"attributes": {
"value": "1"
}
}
}
}
}
}
}
이 XML의 변형은 다음과 같습니다.
<system>
<product>
<demod>
<frequency value='2.215' units='MHz'>
<blah value='1'/>
</frequency>
</demod>
</product>
</system>
여전히 이것이 필요할 수있는 사람에게. 이 변환을 수행하는 새롭고 간단한 코드가 있습니다.
from xml.etree import ElementTree as ET
xml = ET.parse('FILE_NAME.xml')
parsed = parseXmlToJson(xml)
def parseXmlToJson(xml):
response = {}
for child in list(xml):
if len(list(child)) > 0:
response[child.tag] = parseXmlToJson(child)
else:
response[child.tag] = child.text or ''
# one-liner equivalent
# response[child.tag] = parseXmlToJson(child) if len(list(child)) > 0 else child.text or ''
return response
jsonpickle 또는 feedparser를 사용하는 경우 feed_parser_to_json.py를 사용해보십시오 .
내 대답 주소를 특정 (다소 공통)의 경우는 정말 전체 XML로 변환 할 필요가 없습니다 JSON으로,하지만 당신이 필요는 XML의 트래버스 / 액세스 특정 부품에, 당신은 그것을 할 필요가 신속 하고, 단순합니다 (json / dict-like 연산 사용).
접근하다
이를 위해 xml을 etree로 파싱하는 lxml
것은 매우 빠릅니다. 대부분의 다른 답변에서 느린 부분은 두 번째 단계입니다 .etree 구조를 통과 (일반적으로 python-land)하여 json으로 변환합니다.
이 경우 내가 가장 잘 찾은 접근 방식으로 lxml
연결됩니다.
암호
코드는 다음과 같습니다.
from collections import Mapping
import lxml.etree
class ETreeDictWrapper(Mapping):
def __init__(self, elem, attr_prefix = '@', list_tags = ()):
self.elem = elem
self.attr_prefix = attr_prefix
self.list_tags = list_tags
def _wrap(self, e):
if isinstance(e, basestring):
return e
if len(e) == 0 and len(e.attrib) == 0:
return e.text
return type(self)(
e,
attr_prefix = self.attr_prefix,
list_tags = self.list_tags,
)
def __getitem__(self, key):
if key.startswith(self.attr_prefix):
return self.elem.attrib[key[len(self.attr_prefix):]]
else:
subelems = [ e for e in self.elem.iterchildren() if e.tag == key ]
if len(subelems) > 1 or key in self.list_tags:
return [ self._wrap(x) for x in subelems ]
elif len(subelems) == 1:
return self._wrap(subelems[0])
else:
raise KeyError(key)
def __iter__(self):
return iter(set( k.tag for k in self.elem) |
set( self.attr_prefix + k for k in self.elem.attrib ))
def __len__(self):
return len(self.elem) + len(self.elem.attrib)
# defining __contains__ is not necessary, but improves speed
def __contains__(self, key):
if key.startswith(self.attr_prefix):
return key[len(self.attr_prefix):] in self.elem.attrib
else:
return any( e.tag == key for e in self.elem.iterchildren() )
def xml_to_dictlike(xmlstr, attr_prefix = '@', list_tags = ()):
t = lxml.etree.fromstring(xmlstr)
return ETreeDictWrapper(
t,
attr_prefix = '@',
list_tags = set(list_tags),
)
이 구현은 완전하지 않습니다. 예를 들어, 요소에 텍스트와 속성이 모두 있거나 텍스트와 자식이 모두있는 경우를 명확하게 지원하지 않습니다 (작성할 때 필요하지 않았기 때문에 만). 그래도 그것을 개선하기 위해.
속도
XML의 특정 요소 만 처리 해야하는 특정 사용 사례 에서이 접근법은 @Martin Blech의 xmltodict 를 사용한 다음 dict을 직접 통과하는 것과 비교하여 놀랍고 놀라운 속도를 70 (!) 까지 높였습니다 .
보너스
보너스로, 우리의 구조는 이미 dict-like와 같으므로 다른 대안 xml2json
을 무료로 구현할 수 있습니다. dict-like 구조체를로 전달하면 json.dumps
됩니다. 다음과 같은 것 :
def xml_to_json(xmlstr, **kwargs):
x = xml_to_dictlike(xmlstr, **kwargs)
return json.dumps(x)
xml에 속성이 포함 된 경우 attr_prefix
키가 유효한 json 키가되도록 영숫자 (예 : "ATTR_") 를 사용해야 합니다.
이 부분을 벤치마킹하지 않았습니다.
여기에있는 것들이 적극적으로 유지되고 있으며 지금까지 내가 가장 좋아하는 것은 : xml2json in python
lxml2json을 확인하십시오 (공개 : 내가 썼습니다)
https://github.com/rparelius/lxml2json
매우 빠르고 가벼우 며 (lxml 만 필요) 한 가지 장점은 특정 요소가 목록 또는 dicts로 변환되는지 여부를 제어 할 수 있다는 것입니다
declxml을 사용할 수 있습니다. 다중 속성 및 복잡한 중첩 지원과 같은 고급 기능이 있습니다. 간단한 프로세서 만 작성하면됩니다. 또한 동일한 코드를 사용하여 JSON으로 다시 변환 할 수도 있습니다. 그것은 매우 간단하고 문서는 훌륭합니다.
링크 : https://declxml.readthedocs.io/en/latest/index.html
Python 에서 데이터 준비 : JSON을 먼저 만들려면 Python 에서 데이터 를 준비해야합니다. 파이썬에서 List와 Dictionary를 사용하여 데이터를 준비 할 수 있습니다.
Python Dictionary <==> JSON Object (Key Value Format) 자세한 내용은 이것을 확인하십시오.
https://devstudioonline.com/article/create-json-and-xml-in-python
JSON 형식으로 데이터를 나타내려면
name=John
age=20
gender=male
address=Sector 12 Greater Kailash, New Delhi
Jobs=Noida,Developer | Gurugram,Tester |Faridabad,Designer
에서 JSON 우리는 키와 값 형식의 데이터를 repesent
{
"name":"john",
"age":20,
"gender":"male",
"address":["New kP college","Greater Kailash","New Delhi"],
"jobs":[
{"Place":"Noida","Title":"Developer "},
{"Place":"Gurugram","Title":"Tester "},
{"Place":"Faridabad","Title":"Designer"}
]
}
XML 형식으로 데이터를 나타내려면
<!-- In xml we write a code under a key you can take any key -->
<info> <!-- key open -->
<name> john </name>
<age> 20 </age>
<gender> male </gender>
<address>
<item> New kP college </item>
<item> Greater Kailash </item>
<item> New Delhi </item>
</address>
<jobs>
<item>
<title>Developer </title>
<place>Noida</place>
</item>
<item>
<title>Designer</title>
<place>Gurugram</place>
</item>
<item>
<title>Developer </title>
<place>Faridabad</place>
</item>
</jobs>
</info> <!-- key close-->
참고 URL : https://stackoverflow.com/questions/191536/converting-xml-to-json-using-python
'development' 카테고리의 다른 글
Xcode 4.3에서 "응용 프로그램에 유효한 'aps-environment'인 타이틀먼트 문자열이 없습니다"를 수정하는 방법은 무엇입니까? (0) | 2020.06.09 |
---|---|
JSON 파일의 몽고 임포트 (0) | 2020.06.09 |
범위를 벗어난 배열에 액세스하면 오류가 발생하지 않습니다. 왜 그렇습니까? (0) | 2020.06.09 |
플로팅 액션 버튼 (패브)의 아이콘 크기 조정 (0) | 2020.06.08 |
테이블과 tr 너비로 정렬 가능한 jquery UI (0) | 2020.06.08 |