Поиск в каталоге Python LXML

Я делаю файл SCons для создания документации Docbook. Для отслеживания зависимостей я хотел бы разрешить поиск файлов каталога по абсолютному пути к файлу.

Скажем так, у меня есть немного Docbook XML:

<book xmlns="http://docbook.org/ns/docbook"
      xmlns:xi="http://www.w3.org/2001/XInclude">

  <info> 
    <title>Docbook example document</title>

    <xi:include href="file:///common/logo.xml"
        xpointer="logo"/>

  </info>
  <xi:include href="chap1/chap1.xml"/>
  <xi:include href="chap2/chap2.xml"/>
  <xi:include href="chap3/chap3.xml"/>
  <xi:include href="chap4/chap4.xml"/>

</book>

и файл catalog.xml:

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">

  <rewriteURI
    uriStartString="file:///stylesheet/"
    rewritePrefix="file:///home/kst/svn/TOOLS/Docbook/stylesheet/" />

  <rewriteURI
    uriStartString="file:///common/"
    rewritePrefix="file:///home/kst/svn/TOOLS/Docbook/common/" />


  <nextCatalog  catalog="/etc/xml/catalog" />

</catalog>

Получение строки xinclude href не проблема при использовании lxml, но я застрял там. Мне нужен какой-то способ получить абсолютное имя файла, к которому файл:///common/logo.xml разрешает (в данном случае /home/kst/svn/TOOLS/Docbook/common/logo.xml) из файла каталога. Это должен быть какой-то код Python, чтобы я мог использовать его в своем файле SConstruct без особых хлопот.

Любая помощь приветствуется.

1 ответ

Решение

Lxml использует поддержку каталога из libxml2. Используйте переменную среды XML_CATALOG_FILES предоставить список каталогов (вы также можете установить его из python, используя os.environ), или, если эта переменная отсутствует, она проверяет наличие /etc/xml/catalog (не могу использовать это на окнах, конечно).

Альтернативой может быть использование пользовательского распознавателя URI. Вы можете найти больше информации в документации LXML

РЕДАКТИРОВАТЬ: очевидно, вопрос был не о фактической обработке xinclude, которая работает, а о способе "запросить" каталог или спросить его о реальных именах файлов, которые будут использоваться для включений.

Lxml (по крайней мере, в настоящее время) не имеет API для этого. Однако базовая библиотека libxml2 поддерживает это, и "оригинальные" привязки libxml2 python позволяют вам сделать это (хотя простая документация отсутствует, однако строки документации в исходном коде libxml2 помогают, однако). Таким образом, хотя этот модуль не так удобен в использовании, как lxml, он кажется лучшим выбором. Пример, который, кажется, работает:

>>> import libxml2
>>> libxml2.loadCatalog('catalog.xml')
>>> print libxml2.catalogResolveURI('file:///common/logo.xml')
file:///home/kst/svn/TOOLS/Docbook/common/logo.xml
Другие вопросы по тегам