2016-05-31 3 views
1

Прямо сейчас у меня есть код, который использует API-интерфейс Biopython и NCBI Entrez для получения XML-строк из Pubmed Central. Я пытаюсь разобрать XML с ElementTree, чтобы просто получить текст со страницы. Хотя у меня есть код BeautifulSoup, который делает именно это, когда я очищаю данные lxml с самого сайта, я перехожу на NCBI API, поскольку скребки, по-видимому, не имеют никакого значения. Но теперь с XML из API NCBI, я считаю ElementTree крайне неинтуитивным и действительно может использовать некоторую помощь, чтобы заставить его работать. Конечно, я просмотрел другие сообщения, но большинство из них касается пространств имен, и в моем случае я просто хочу использовать теги XML для захвата информации. Даже документация ElementTree не входит в это (из того, что я могу сказать). Может ли кто-нибудь помочь мне разобраться в синтаксисе для захвата информации в определенных тегах, а не в определенных пространствах имен?Проблема с получением текста из XML с помощью ElementTree с тегами

Вот пример. Примечание: Я использую Python 3.4

Малый Snippit в XML:

 <sec sec-type="materials|methods" id="s5"> 
     <title>Materials and Methods</title> 
     <sec id="s5a"> 
     <title>Overgo design</title> 
     <p>In order to screen the saltwater crocodile genomic BAC library described below, four overgo pairs (forward and reverse) were designed (<xref ref-type="table" rid="pone-0114631-t002">Table 2</xref>) using saltwater crocodile sequences of MHC class I and II from previous studies <xref rid="pone.0114631-Jaratlerdsiri1" ref-type="bibr">[40]</xref>, <xref rid="pone.0114631-Jaratlerdsiri3" ref-type="bibr">[42]</xref>. The overgos were designed using OligoSpawn software, with a GC content of 50&#x2013;60% and 36 bp in length (8-bp overlapping) <xref rid="pone.0114631-Zheng1" ref-type="bibr">[77]</xref>. The specificity of the overgos was checked against vertebrate sequences using the basic local alignment search tool (BLAST; <ext-link ext-link-type="uri" xlink:href="http://www.ncbi.nlm.nih.gov/">http://www.ncbi.nlm.nih.gov/</ext-link>).</p> 
    <table-wrap id="pone-0114631-t002" orientation="portrait" position="float"> 
     <object-id pub-id-type="doi">10.1371/journal.pone.0114631.t002</object-id> 
     <label>Table 2</label> 
     <caption> 
     <title>Four pairs of forward and reverse overgos used for BAC library screening of MHC-associated BACs.</title> 
     </caption> 
     <alternatives> 
     <graphic id="pone-0114631-t002-2" xlink:href="pone.0114631.t002"/> 
     <table frame="hsides" rules="groups"> 
      <colgroup span="1"> 
      <col align="left" span="1"/> 
      <col align="center" span="1"/> 
      </colgroup> 

Для моего проекта, я хочу весь текст в «р» метки (не только для этого Snippit в XML, но для всей строки XML).

Теперь я уже знаю, что я могу сделать всю строку XML в объект ElementTree

>>> import xml.etree.ElementTree as ET 
>>> tree = ET.ElementTree(ET.fromstring(xml_string)) 
>>> root = ET.fromstring(xml_string) 

Теперь, если я пытаюсь получить текст с помощью тега, как это:

>>> text = root.find('p') 
>>> print("".join(text.itertext())) 

или

>>> text = root.get('p').text 

Я не могу извлечь текст, который я хочу. Из того, что я читал, это потому, что я использую тег «p» как аргумент, а не пространство имен.

В то время как я чувствую, что для всего текста должно быть достаточно всего текста в тегах «p» в XML-файле, в настоящее время я не могу этого сделать. Пожалуйста, дайте мне знать, что мне не хватает, и как я могу это исправить. Благодаря!

--- EDIT ---

Так что теперь я знаю, что я должен использовать этот код, чтобы получить все, что в тегах «р»:

>>> text = root.find('.//p') 
>>> print("".join(text.itertext())) 

Несмотря на то, что я используя itertext(), он возвращает только контент из первого тега «p» и не рассматривает какой-либо другой контент. Является ли itertext() только итерацией внутри тега? Документация, похоже, предполагает, что она выполняет итерации по всем тегам, поэтому я не уверен, почему она возвращает только одну строку, а не весь текст под всеми тегами «p».

---- FINAL EDIT -

Я понял, что itertext() работает только в пределах одного тега и найти() возвращает только первый элемент. Для того, чтобы получить enitre текст, который я хочу, я должен использовать FindAll()

>>> all_text = root.findall('.//p') 
>>> for texts in all_text: 
    print("".join(texts.itertext())) 

ответ

1

root.get() неправильный метод, так как он будет получать атрибут корневой тег а не Subtag. root.find() правильный, поскольку он найдет первый соответствующий подзаголовок (в качестве альтернативы можно использовать root.findall() для все соответствующие подзаголовки).

Если вы хотите найти не только прямые subtags, но и косвенные subtags (как в вашем примере), выражение внутри root.find/root.findall должно быть подмножеством XPath (см. https://docs.python.org/2/library/xml.etree.elementtree.html#xpath-support). В вашем случае это «.//p»:

text = root.find('.//p') 
    print("".join(text.itertext())) 
+0

Очень приятно знать, спасибо! Я недостаточно знаком с этими аспектами XML, поэтому ваша обратная связь действительно помогла. Когда я запускал ваш код, мой терминал печатал только одну строку текста из тега «p». Из того, что я собираю, «itertext» должен избегать этого. Любая идея, что происходит? – SnarkShark

 Смежные вопросы

  • Нет связанных вопросов^_^