首页 > 解决方案 > 如何使用 minidom 访问元素的子元素?

问题描述

我正在 Jupyter 笔记本中读取 XML/OWL 文件(从 Protege 生成)。

我可以读取根元素,但对于孩子来说,它显示错误/空白。

from xml.dom.minidom import parse

DOMTree = parse("pressman.owl")
collection = DOMTree.documentElement

if collection.hasAttribute("shelf"):
   print("Root element : %s" % collection.getAttribute("owl:ObjectProperty"))

for objectprop in collection.getElementsByTagName("owl:ObjectProperty"):
    if objectprop.hasAttribute("rdf:about"):
            propertytext = objectprop.getAttribute("rdf:about")
            property = propertytext.split('#',2)
            print ("Property: %s" % property[1])
            type = objectprop.getElementsByTagName('rdf:resource')
            print ("Type: %s" % type)

pressman.owl文件(删节):

<rdf:RDF xmlns="http://www.semanticweb.org/sraza/ontologies/2021/4/untitled-ontology-6#"
     xml:base="http://www.semanticweb.org/sraza/ontologies/2021/4/untitled-ontology-6"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:PressmanOntology="urn:absolute:PressmanOntology#"
     xmlns:UniversityOntology="http://www.semanticweb.org/sraza/ontologies/2021/4/UniversityOntology#">
    <owl:Ontology rdf:about="urn:absolute:PressmanOntology"/>
    
    <!-- Object Properties -->

    <owl:ObjectProperty rdf:about="urn:absolute:PressmanOntology#hasAdvice"/>

    <owl:ObjectProperty rdf:about="urn:absolute:PressmanOntology#hasDefinition">
        <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
        <rdfs:domain rdf:resource="urn:absolute:PressmanOntology#SEPressman"/>
        <rdfs:range rdf:resource="urn:absolute:PressmanOntology#SEPressman"/>
    </owl:ObjectProperty>

    <owl:ObjectProperty rdf:about="urn:absolute:PressmanOntology#hasDiagram">
        <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
        <rdfs:domain rdf:resource="urn:absolute:PressmanOntology#SEPressman"/>
        <rdfs:range rdf:resource="urn:absolute:PressmanOntology#SEPressman"/>
    </owl:ObjectProperty>

    <!-- more entries... -->    
</rdf:RDF>

输出文件

属性:hasAdvice
类型: []
属性:hasDefinition
类型: []
属性:hasDiagram
类型: []

标签: pythonxmlminidom

解决方案


你有这个结构

<owl:ObjectProperty rdf:about="urn:absolute:PressmanOntology#hasDefinition">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
    <rdfs:domain rdf:resource="urn:absolute:PressmanOntology#SEPressman"/>
    <rdfs:range rdf:resource="urn:absolute:PressmanOntology#SEPressman"/>
</owl:ObjectProperty>

你正在使用

type = objectprop.getElementsByTagName('rdf:resource')

这是行不通的,因为rdf:resource它不是一个元素,而是一个属性。我假设你感兴趣的属于<rdf:type>. 所以我们需要再往下一层:

rdf_type = objectprop.getElementsByTagName('rdf:type')

现在rdf_type是一个节点列表 - 毕竟该方法被称为"get element s by tag name",并且 minidom 无法知道您的情况可能只有一个<rdf:type>。如果存在,我们采用第一个:

rdf_type = rdf_type[0] if len(rdf_type) > 0 else None

现在rdf:resource是该元素的一个属性。属性是通过.getAttribute()minidom 访问的。

从理论上讲,rdf:resourceXML 中可能缺少该属性,因此在使用它之前让我们确保它存在:

if rdf_type is not None and rdf_type.hasAttribute('rdf:resource'):
    rdf_resource = rdf_type.getAttribute('rdf:resource')
else:
    rdf_resource = None

print(rdf_resource)

话虽如此,与其手动处理 RDF 文件,不如检查为 RDF 编写的库,例如rdflib,甚至是专门为 OWL 编写的库,例如pyLODE


推荐阅读