【问题标题】:get list of entities in doctype of xml file获取 xml 文件 doctype 中的实体列表
【发布时间】:2019-10-14 22:17:22
【问题描述】:

使用 python 和 lxml,有没有办法获取 xml 文件的 doctype 中的实体列表? 这是缩小的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 解析文件并检索 doctype 中列出的实体 (!ENTITY) 吗? 我想要最终结果为 ['somegraphic1.cgm', 'somegraphic2.cgm'] 的图形文件列表。 目前,代码(不优雅)只是打开 xml 文件并逐行读取直到&lt;dmodule,然后拆分行以查找以“.cgm”结尾的字符串 - 呸。 如果lxml不能,请推荐另一种方式。

【问题讨论】:

    标签: python lxml


    【解决方案1】:

    如果我对您的理解正确,有一种有点奇怪的方法可以到达那里,它至少可以与上面的精简 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

    【讨论】:

      【解决方案2】:

      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
      

      我使用“//@infoEntityIdent”之类的 XPath 表达式来获取所有使用的图形的列表,然后获取每个图形的实体 URI。请注意,这并未列出 DTD 中声明的所有 ENTITY,仅列出了在 XML 中实际用作 &lt;graphic&gt;s 或 &lt;symbol&gt;s 的那些。

      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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-15
        相关资源
        最近更新 更多