首页 > 解决方案 > root.findall('foo') 和 root.iter('foo') 不返回任何结果

问题描述

我有一个瑞典词典的大型 xml 表示。我正在寻找所有标记为“subst”的名词。在文件中。

这是文件的一部分,它代表单词“a”的一个条目(文章):

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"  href="transform_lexin.xsl"?>
<Dictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="lexinAA.xsd">
  <Article ID="1000002" Sortkey="a">
    <Lemma Value="a" Variant="" Type="subst." ID="1000002" LemmaID="1" VariantID="3, 4" Rank="350">
      <Phonetic File="a.swf">a:</Phonetic>
      <Inflection Form="best.f.sing.">a:et</Inflection>
      <Inflection Form="obest.f.pl.">a:n</Inflection>
      <Inflection Form="best.f.pl.">a:na</Inflection>
      <Index Value="a" />
      <Index Value="a:et" />
      <Index Value="a:n" />
      <Index Value="a:na" />
      <Index Value="as" />
      <Index Value="a:ets" />
      <Index Value="a:ns" />
      <Index Value="a:nas" />
      <Lexeme ID="1" Lexemeno="1" LexemeID="1000006" VariantID="3">
        <Definition>första bokstaven i alfabetet</Definition>
        <Idiom ID="1000008" OldID="2">a och o<Definition ID="1000009">det viktigaste</Definition></Idiom>
        <Idiom ID="1000010" OldID="1">har man sagt a får man också säga b<Definition ID="1000011">har man börjat får man fortsätta</Definition></Idiom>
      </Lexeme>
      <Lexeme ID="2" Lexemeno="2" LexemeID="1000013" VariantID="4">
        <Definition>sjätte tonen i C-durskalan</Definition>
        <Compound OldID="" ID="2000667">a-moll</Compound>
        <Compound OldID="" ID="2000668">A-dur</Compound>
        <Index Value="a-moll" />
        <Index Value="a-molls" />
        <Index Value="a moll" />
        <Index Value="a molls" />
        <Index Value="A-dur" />
        <Index Value="A-durs" />
        <Index Value="A dur" />
        <Index Value="A durs" />
      </Lexeme>
    </Lemma>
  </Article>

当我尝试使用 findall 或 inter 方法查找名词时,它们不会返回任何内容。

import xml.etree.ElementTree as ET
import sys

tree = ET.parse(sys.argv[1])
root = tree.getroot()

for noun in root.findall('subst.'):
      print(noun.attrib)

如果我使用 findall() 和 iter(),我会得到相同的空结果

但是,当我搜索“文章”而不是“替代”时。我得到了所有的字典条目:

for noun in root.iter('Article'):
      print(noun.attrib)
{'ID': '1179604', 'Sortkey': 'övning'}
{'ID': '1179617', 'Sortkey': 'övningskörning'}
{'ID': '1179637', 'Sortkey': 'övre'}
{'ID': '1179644', 'Sortkey': 'övrig'}
{'ID': '1179656', 'Sortkey': 'övärld'}

我尝试了其他关键字,例如“引理”,它不会返回任何内容。当我使用 iter() 但不使用 findall() 时,'Idiom' 返回项目

我显然遗漏了一些关于这些方法如何工作的明显内容。

标签: python-3.xelementtree

解决方案


这是一个 xslt 转换解决方案。由于 xml 源代码很大,您可以通过让 libxml 完成繁重的工作来享受额外的性能。要尝试它,请将以下内容复制到名为 swedish-dictionary.xsl 的文件中:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Dictionary/Article/Lemma[@Type = 'subst.']">
        <xsl:text>{'ID': '</xsl:text>
        <xsl:value-of select="../@ID" />
        <xsl:text>', 'Sortkey': '</xsl:text>
        <xsl:value-of select="../@Sortkey" />
        <xsl:text>'}</xsl:text>
    </xsl:template>
</xsl:stylesheet>

如果 xml 源文件名为 swedish-dictionary.xml,则 python 将如下所示:

from lxml import etree

with open('swedish-dictionary.xsl') as stylesheet:
    transform = etree.XSLT(etree.XML(stylesheet.read()))

with open('swedish-dictionary.xml') as xml:
    print(transform(etree.parse(xml)))

示例 xml 的结果:

{'ID': '1000002', 'Sortkey': 'a'}

您还可以使用 libxml 的 xsltproc 实用程序获得相同的结果:

xsltproc swedish-dictionary.xsl swedish-dictionary.xml

推荐阅读