получить список сущностей в формате документа xml - PullRequest
0 голосов
/ 15 октября 2019

Используя python и lxml, есть ли способ получить список сущностей в типе файла xml? Вот сокращенный xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dmodule [
<!ENTITY somegraphic1 SYSTEM 'somegraphic1.cgm' NDATA cgm>
<!ENTITY somegraphic2 SYSTEM 'somegraphic2.cgm' NDATA cgm>
<!NOTATION cgm SYSTEM 'cgm'>
<!ENTITY % ISOEntities PUBLIC 'ISO 8879-1986//ENTITIES ISO Character Entities 20030531//EN//XML' 'http://www.s1000d.org/S1000D_4-1/ent/xml/ISOEntities'>
%ISOEntities;]>
<dmodule>
<graphic ident="somegraphic1"/>
<graphic ident="somegraphic2"/>
</dmodule>

Могу ли я проанализировать файл с помощью lxml и получить перечисленные объекты (! ENTITY) в типе документа? Я хочу список графических файлов, используемых с возможным результатом ['somegraphic1.cgm', 'somegraphic2.cgm']. В настоящее время код (не элегантно) просто открывает файл xml и читает построчно до <dmodule, а затем разбивает строки в поисках строки, заканчивающейся на «.cgm» - yuck. Если lxml не может, пожалуйста, порекомендуйте другой способ.

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

libxml2 имеет функцию xmlGetDocEntity (doc, name) , которая возвращает объект, представляющий сущность, с полем URI , содержащим непарсированный URI сущности. Это то, что я использовал для инструмента, который делает что-то похожее: https://github.com/kibook/s1kd-tools/tree/master/tools/s1kd-refs.

Пример использования:

$ s1kd-refs --icn DMC-[...].XML
somegraphic1.cgm
somegraphic2.cgm

Я использую выражение XPath вроде "// @ infoEntityIdent", чтобы получить списокиз всей используемой графики, затем выберите URI объекта для каждого из них. Обратите внимание, что здесь не перечислены все ENTITY, объявленные в DTD, только те, которые фактически используются как <graphic> s или <symbol> s в XML.

lxml построен поверх libxml2, но янедостаточно знаком с ним, чтобы знать, существует ли точный эквивалент xmlGetDocEntity.

Другой вариант - сначала использовать XSLT для создания чего-то более простого для анализа:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="/">
      <graphics>
        <xsl:apply-templates select="//@infoEntityIdent"/>
      </graphics>
    </xsl:template>

    <xsl:template match="@infoEntityIdent">
      <graphic>
        <xsl:value-of select="unparsed-entity-uri(.)"/>
      </graphic>
    </xsl:template>

</xsl:transform>

Вывод:

<graphics>
  <graphic>somegraphic1.cgm</graphic>
  <graphic>somegraphic2.cgm</graphic>
</graphics>
0 голосов
/ 15 октября 2019

Если я вас правильно понимаю, есть несколько странный способ добраться до него, и он работает по крайней мере с вашим урезанным xml выше - так что, если он соответствует вашим потребностям, он может быть достаточно хорош ...

myx = """[your xml snippet]"""
from bs4 import BeautifulSoup as bs
soup = bs(myx,'html.parser') #yup, html parser...
for i in soup:           
    if 'ENTITY' in i and 'SYSTEM' in i:
        one = i.split('SYSTEM')
        two = one[1].split('NDATA')
        print(two[0])

Вывод:

somegraphic1.cgm

somegraphic2.cgm

...