root.findall ('foo') и root.iter ('foo') не возвращают никаких результатов - PullRequest
0 голосов
/ 28 сентября 2019

У меня большое xml представление шведского словаря.Я ищу все существительные, которые помечены как «суб».в файле.

Вот раздел файла, который представляет одну запись (статью) для слова '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 ()

Однако, когда я ищу 'Articleвместо «саб.»Я получаю все словарные записи:

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'}

Я пробовал другие ключевые слова, такие как «Лемма», которые ничего не возвращают.'Idiom' возвращает элементы, когда я использую iter (), но не findall ()

Я явно упускаю что-то очевидное в том, как работают эти методы.

Ответы [ 2 ]

0 голосов
/ 29 сентября 2019

Вот способ поиска Article элементов с дочерним элементом Lemma, чей атрибут Type имеет значение subst.:

import xml.etree.ElementTree as ET

tree = ET.parse("dictionary.xml")

for article in tree.findall("Article"):
    lemma = article.find("Lemma")
    if lemma and lemma.get("Type") == "subst.":
        print(article.attrib)

Вывод:

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

С lxml вы можете использовать компактное выражение XPath для получения того же результата:

from lxml import etree

tree = etree.parse("article.xml")

for article in tree.xpath("Article[Lemma[@Type='subst.']]"):
    print(article.attrib)
0 голосов
/ 29 сентября 2019

Вот решение преобразования 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, питон будет выглядеть следующим образом:

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
...