【问题标题】:Retrieve value of child node given attribute using Python使用Python检索给定属性的子节点的值
【发布时间】:2019-11-19 11:55:15
【问题描述】:

我有一个以下格式的 XSD 文件:

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:type name="type1">
        <xsd:example>
          <xsd:description>This is the description of said type1 tag</xsd:description>
        </xsd:example>
    </xsd:type>
    <xsd:type name="type2">
        <xsd:example>
          <xsd:description>This is the description of said type2 tag</xsd:description>
        </xsd:example>
    </xsd:type>
    <xsd:type name="type3">
        <xsd:example>
          <xsd:description>This is the description of said type3 tag</xsd:description>
        </xsd:example>
    </xsd:type>
</xsd:schema>

以及以下 XML 文件:

<theRoot>
    <type1>hi from type1</type1>
    <theChild>
        <type2>hi from type2</type2>
        <type3>hi from type3</type3>
    </theChild>
</theRoot>

我想检索 xsd:description 标记之间的值,因为它是具有 name="type1" 属性的 xsd:type 标记的子项。换句话说,我想检索“This is the description of the type1 tag”。

我已尝试使用 Python 以下列方式对 lxml 执行此操作:

from lxml import etree
XSDDoc = etree.parse(xsdFile)
root = XSDDoc.getroot()
result = root.findall(".//xsd:type/xsd:example/xsd:description[@name='type1']", root.nsmap)

我使用了here 提到的相同示例和解决方案。但是,我所做的只是返回空结果,我无法检索到正确的结果。

作为参考,我的 Python 版本是:Python 2.7.10

编辑: 当我通过从字符串中检索 XML 结构来使用答案中提供的示例时,结果符合预期。但是,当我尝试从文件中检索时,会返回空列表(或无)。

我正在做以下事情:

  • 从文件中检索 XML
  • 包含一个变量来表示名称属性(因为它是动态的)

代码在单独的 XML 文件中遍历每个节点,然后检查 XSD 文件以获取每个属性作为结果:

XMLDoc = etree.parse(open(xmlFile))

for Node in XMLDoc.xpath('//*'):
    nameVariable = os.path.basename(XMLDoc.getpath(Node))
    root = XSDDoc.getroot()
    description = XSDDoc.find(".//xsd:type[@name='{0}']/xsd:example/xsd:description".format(nameVariable), root.nsmap)

如果我尝试打印出result.text,我会得到:

AttributeError: 'NoneType' 对象没有属性 'text'

【问题讨论】:

  • 你到底尝试了什么?在问题的代码中,您不会尝试获取 xsd:description 元素(这是 xsd:type 的孙子元素)。
  • @mzjn 抱歉,因为我不得不删除一些敏感信息,所以我省略了 xsd:type 之后的剩余路径。我已编辑问题以反映我的确切代码。
  • 这不是真正的“确切”代码(nameVariable 是什么?)请提供minimal reproducible example
  • 我已经编辑了我的问题。 nameVariable 只是一个字符串。
  • 很抱歉对此唠叨不休,但当我要求 minimal reproducible example 时,我的意思是 完整但最少 代码(和 XML),我可以在没有这些代码(和 XML)的情况下复制、粘贴和运行改变任何东西。

标签: python xml


【解决方案1】:

谓词 ([@name='type1']) 必须应用在正确的位置。 name 属性位于 xsd:type 元素上。这应该有效:

result = root.findall(".//xsd:type[@name='type1']/xsd:example/xsd:description", root.nsmap)

# result is a list
for r in result:
    print(r.text)

如果您只需要一个节点,您可以使用find 而不是findall。完整示例:

from lxml import etree

xsdFile = """
<root xmlns:xsd='http://whatever.com'>
 <xsd:type name="type1">
     <xsd:example>
       <xsd:description>This is the description of said type1 tag</xsd:description>
     </xsd:example>
 </xsd:type>
</root>"""

root = etree.fromstring(xsdFile)
result = root.find(".//xsd:type[@name='type1']/xsd:example/xsd:description", root.nsmap)

print(result.text)

【讨论】:

  • 感谢您的回答。然而,那段代码返回一个空列表,而不是任何包含标签内值的东西。
  • 另外,我相信代码会返回一个列表对象。如何从该列表对象中提取 value 属性?
  • 再次感谢您的帮助。我根据您的回答编辑了我的问题。有空的时候请看一下。
猜你喜欢
  • 1970-01-01
  • 2021-09-23
  • 2011-05-30
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多