'Element'를 통해 Python에서 네임스페이스가 있는 XML 구문 분석나무'
파이썬을 사용하여 구문 분석하고 싶은 다음 XML이 있습니다.ElementTree
:
<rdf:RDF xml:base="http://dbpedia.org/ontology/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns="http://dbpedia.org/ontology/">
<owl:Class rdf:about="http://dbpedia.org/ontology/BasketballLeague">
<rdfs:label xml:lang="en">basketball league</rdfs:label>
<rdfs:comment xml:lang="en">
a group of sports teams that compete against each other
in Basketball
</rdfs:comment>
</owl:Class>
</rdf:RDF>
모두 찾고 싶습니다.owl:Class
태그를 지정한 다음 모두의 값을 추출합니다.rdfs:label
그들 내부의 예들.다음 코드를 사용하고 있습니다.
tree = ET.parse("filename")
root = tree.getroot()
root.findall('owl:Class')
네임스페이스 때문에 다음과 같은 오류가 발생합니다.
SyntaxError: prefix 'owl' not found in prefix map
http://effbot.org/zone/element-namespaces.htm 에서 문서를 읽으려고 했지만 위의 XML에 여러 개의 중첩된 이름 공간이 있기 때문에 여전히 이 작업을 수행할 수 없습니다.
모든 것을 찾기 위해 코드를 변경하는 방법을 알려주세요.owl:Class
꼬리표
당신은 그것을 줄 필요가 있습니다..find()
,findall()
그리고.iterfind()
메서드: 명시적 네임스페이스 사전:
namespaces = {'owl': 'http://www.w3.org/2002/07/owl#'} # add more as needed
root.findall('owl:Class', namespaces)
접두사는 에서만 검색됩니다.namespaces
매개 변수를 입력합니다.즉, 원하는 네임스페이스 접두사를 사용할 수 있습니다. API는 다음과 같이 분리됩니다.owl:
part, 에서 해당 네임스페이스 URL을 검색합니다.namespaces
사전을 선택한 다음 검색을 변경하여 XPath 식을 찾습니다.{http://www.w3.org/2002/07/owl}Class
대신.물론 동일한 구문을 사용할 수도 있습니다.
root.findall('{http://www.w3.org/2002/07/owl#}Class')
요소의 네임스페이스를 사용한 XML 구문 분석 섹션도 참조하십시오.트리 문서.
라이브러리로 전환할 수 있으면 라이브러리가 동일한 요소를 지원하는 것이 더 좋습니다.트리 API, 그러나 사용자에 대한 네임스페이스를 수집합니다..nsmap
요소에 대한 속성이며 일반적으로 우수한 네임스페이스 지원을 제공합니다.
다음은 네임스페이스를 하드 코딩하거나 텍스트를 스캔하지 않고 lxml로 이 작업을 수행하는 방법입니다(Martjn Pieters가 언급한 바와 같이).
from lxml import etree
tree = etree.parse("filename")
root = tree.getroot()
root.findall('owl:Class', root.nsmap)
업데이트:
5년이 지난 지금도 저는 이 문제의 다양성에 직면해 있습니다.위에서 보여드린 것처럼 lxml이 도움이 되지만 모든 경우에 도움이 되는 것은 아닙니다.의견제출자들은 문서 병합에 관한 이 기법에 대해 타당한 지적을 할 수 있지만, 대부분의 사람들이 단순히 문서를 검색하는 데 어려움을 겪고 있다고 생각합니다.
다음은 제가 처리한 또 다른 사례입니다.
<?xml version="1.0" ?><Tag1 xmlns="http://www.mynamespace.com/prefix">
<Tag2>content</Tag2></Tag1>
접두사가 없는 xmlns는 접두사가 없는 태그가 이 기본 네임스페이스를 수신함을 의미합니다.즉, 태그2를 검색할 때 네임스페이스를 포함해야 태그2를 찾을 수 있습니다.하지만 lxml은 없음을 키로 하는 nsmap 항목을 생성하여 검색할 방법을 찾지 못했습니다.그래서 이렇게 새로운 네임스페이스 사전을 만들었습니다.
namespaces = {}
# response uses a default namespace, and tags don't mention it
# create a new ns map using an identifier of our choice
for k,v in root.nsmap.iteritems():
if not k:
namespaces['myprefix'] = v
e = root.find('myprefix:Tag2', namespaces)
메모Python's Element에 유용한 답변입니다.하드 코딩된 네임스페이스를 사용하지 않는 트리 표준 라이브러리.
하려면 XML 데이를네스의이접두및 URI데사용있다를 사용할 수 .ElementTree.iterparse
함수, 네임스페이스 시작 이벤트만 구문 분석(start-ns):
>>> from io import StringIO
>>> from xml.etree import ElementTree
>>> my_schema = u'''<rdf:RDF xml:base="http://dbpedia.org/ontology/"
... xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
... xmlns:owl="http://www.w3.org/2002/07/owl#"
... xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
... xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
... xmlns="http://dbpedia.org/ontology/">
...
... <owl:Class rdf:about="http://dbpedia.org/ontology/BasketballLeague">
... <rdfs:label xml:lang="en">basketball league</rdfs:label>
... <rdfs:comment xml:lang="en">
... a group of sports teams that compete against each other
... in Basketball
... </rdfs:comment>
... </owl:Class>
...
... </rdf:RDF>'''
>>> my_namespaces = dict([
... node for _, node in ElementTree.iterparse(
... StringIO(my_schema), events=['start-ns']
... )
... ])
>>> from pprint import pprint
>>> pprint(my_namespaces)
{'': 'http://dbpedia.org/ontology/',
'owl': 'http://www.w3.org/2002/07/owl#',
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'rdfs': 'http://www.w3.org/2000/01/rdf-schema#',
'xsd': 'http://www.w3.org/2001/XMLSchema#'}
그런 다음 사전을 인수로 검색 기능에 전달할 수 있습니다.
root.findall('owl:Class', my_namespaces)
저는 이와 유사한 코드를 사용해왔고 문서를 항상 읽을 가치가 있다는 것을 알게 되었습니다.여느 때처럼!
find all ()는 현재 태그의 직접 자식 요소만 찾습니다.전부는 아닙니다.
특히 크고 복잡한 xml 파일을 처리하여 하위 요소(예: 하위 요소)도 포함되도록 하는 경우에는 코드를 다음과 같이 사용해 보는 것이 좋습니다.만약 당신이 당신의 xml에서 요소들이 어디에 있는지 알고 있다면, 나는 그것이 괜찮을 것이라고 생각합니다!기억할 만한 가치가 있다고 생각했어요
root.iter()
ref: https://docs.python.org/3/library/xml.etree.elementtree.html#finding-interesting-elements "Element.findall()은 현재 요소의 직접 자식인 태그가 있는 요소만 찾습니다.Element.find()는 특정 태그가 있는 첫 번째 자식을 찾고 Element.text는 요소의 텍스트 내용에 액세스합니다.Element.get()은 요소의 속성에 액세스합니다."
네임스페이스 형식으로 네임스페이스를 가져오려면 다음과 같이 하십시오.{myNameSpace}
다음을 수행할 수 있습니다.
root = tree.getroot()
ns = re.match(r'{.*}', root.tag).group(0)
이러한 방식으로 나중에 코드에서 문자열 보간(Python 3) 등을 사용하여 노드를 찾을 수 있습니다.
link = root.find(f"{ns}link")
이것은 기본적으로 David Brunato의 대답이지만, 저는 그의 대답이 적어도 제 파이썬 3.6 설치에서 기본 네임스페이스인 빈 문자열에 심각한 문제가 있다는 것을 발견했습니다.그의 코드에서 추출한 기능은 다음과 같습니다.
from io import StringIO
from xml.etree import ElementTree
def get_namespaces(xml_string):
namespaces = dict([
node for _, node in ElementTree.iterparse(
StringIO(xml_string), events=['start-ns']
)
])
namespaces["ns0"] = namespaces[""]
return namespaces
ns0
빈 네임스페이스에 대한 자리 표시자일 뿐이며 원하는 임의의 문자열로 바꿀 수 있습니다.
내가 하면 됩니다.
my_namespaces = get_namespaces(my_schema)
root.findall('ns0:SomeTagWithDefaultNamespace', my_namespaces)
또한 기본 네임스페이스를 사용하는 태그에 대한 정답도 생성합니다.
제 해결책은 @Martijn Pieters의 논평에 기초하고 있습니다.
register_namespace
직렬화에만 영향을 미치며 검색에는 영향을 주지 않습니다.
그래서 여기서 요령은 직렬화와 검색을 위해 다른 사전을 사용하는 것입니다.
namespaces = {
'': 'http://www.example.com/default-schema',
'spec': 'http://www.example.com/specialized-schema',
}
이제 구문 분석 및 쓰기를 위해 모든 네임스페이스를 등록합니다.
for name, value in namespaces.iteritems():
ET.register_namespace(name, value)
을 위해 색용검(find()
,findall()
,iterfind()
비어 있지 않은 접두사가 필요합니다.이러한 함수에 수정된 사전을 전달합니다(여기서는 원래 사전을 수정하지만 이름 공간이 등록된 후에만 수정해야 합니다).
self.namespaces['default'] = self.namespaces['']
그럼 이제 제은, .find()
는 패리를사수있다니습과 할 수 .default
접두사:
print root.find('default:myelem', namespaces)
그렇지만
tree.write(destination)
에서는 기본 네임스페이스의 요소에 접두사를 사용하지 않습니다.
언급URL : https://stackoverflow.com/questions/14853243/parsing-xml-with-namespace-in-python-via-elementtree
'programing' 카테고리의 다른 글
최신 버전의 gcc에서 c11을 활성화하는 방법은 무엇입니까? (0) | 2023.07.01 |
---|---|
sp_dbcmpt 수준이 더 이상 사용되지 않는 경우 SQL Server 데이터베이스 호환성을 확인하는 방법은 무엇입니까? (0) | 2023.07.01 |
HEAD, 마스터, 오리진의 깃 개념은 무엇입니까? (0) | 2023.07.01 |
stdout을 일종의 문자열 버퍼로 리디렉션할 수 있습니까? (0) | 2023.07.01 |
함수에 다차원 변수 길이 배열 전달 (0) | 2023.07.01 |