lxml包含相对路径 [英] lxml include relative path

查看:55
本文介绍了lxml包含相对路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Python的lxml库来加载.xsd作为架构.Python脚本位于一个目录中,而模式位于另一个目录中:

Using Python's lxml library, I'm trying to load a .xsd as schema. The Python script is in one directory and the schemas are in another:

/root
    my_script.py
    /data
        /xsd
            schema_1.xsd
            schema_2.xsd

问题在于 schema_1.xsd 包含 schema_2.xsd 如下:

<xsd:include schemaLocation="schema_2.xsd"/>

作为 schema_2.xsd 的相对路径(两个模式位于同一目录中),lxml找不到它,并且它会上升并出现错误:

Being schema_2.xsd a relative path (the two schemas are in the same directory), lxml doesn't find it and it rises and error:

schema_root = etree.fromstring(open('data/xsd/schema_1.xsd').read().encode('utf-8'))
schema = etree.XMLSchema(schema_root)

--> xml.etree.XMLSchemaParseError: Element '{http://www.w3.org/2001/XMLSchema}include': Failed to load the document './schema_2.xsd' for inclusion

如何在不改变架构文件的情况下解决这个问题?

How to solve this problem without changing the schema files?

推荐答案

一种选择是使用 URI解析器,但是我一直使用目录.非开发人员更容易进行配置更改.如果您要提供的是可执行文件而不是普通的Python,这将特别有用.

One option is to use an XML Catalog. You could also probably use a custom URI Resolver, but I've always used a catalog. It's easier for non-developers to make configuration changes. This is especially helpful if you're delivering an executable instead of plain Python.

在Windows和Linux中,使用目录有所不同;有关详细信息,请参见此处.

Using a catalog is different between Windows and Linux; see here for more info.

这是一个使用Python 3.#的Windows示例.

Here's a Windows example using Python 3.#.

XSD#1 (schema_1.xsd)

XSD #1 (schema_1.xsd)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:include schemaLocation="schema_2.xsd"/>

  <xs:element name="doc">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="test"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="test" type="test"/>
</xs:schema>

XSD#2 (schema_2.xsd)

XSD #2 (schema_2.xsd)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:simpleType name="test">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Hello World"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

XML目录(catalog.xml)

XML Catalog (catalog.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE catalog PUBLIC "-//OASIS//DTD XML Catalogs V1.1//EN" "http://www.oasis-open.org/committees/entity/release/1.1/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
    <!-- The path in @uri is relative to this file (catalog.xml). -->
    <system systemId="schema_2.xsd" uri="./xsd_test/schema_2.xsd"/>
</catalog>

Python

import os
from urllib.request import pathname2url
from lxml import etree

# The XML_CATALOG_FILES environment variable is used by libxml2 (which is used by lxml).
# See http://xmlsoft.org/catalog.html.
if "XML_CATALOG_FILES" not in os.environ:
    # Path to catalog must be a url.
    catalog_path = f"file:{pathname2url(os.path.join(os.getcwd(), 'catalog.xml'))}"
    # Temporarily set the environment variable.
    os.environ['XML_CATALOG_FILES'] = catalog_path

schema_root = etree.fromstring(open('xsd_test/schema_1.xsd').read().encode('utf-8'))
schema = etree.XMLSchema(schema_root)

print(schema)

打印输出

<lxml.etree.XMLSchema object at 0x02B4B3F0>

这篇关于lxml包含相对路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆