2016-01-20 5 views
1

Мой python libxml2 по-разному обрабатывает файлы с атрибутами по умолчанию, в зависимости от того, что я хочу знать. Пример, используя DITA DTD (пакет можно загрузить на www.dita-ot.org):Развернуть атрибуты default (dita)

import libxml2 
import libxsltmod 

s = """<!DOCTYPE map PUBLIC "-//OASIS//DTD XDITA Map//EN" 
"file://.../dita-ot-2.2.1/plugins/org.oasis-open.dita.v1 
_2/dtd/technicalContent/dtd/map.dtd"> 

<map title="Empty map"> 
</map>""" 

libxml2.substituteEntitiesDefault(1) 
xmldoc = libxml2.parseDoc(s) 
print xmldoc 

Выход по желанию:

<?xml version="1.0"?> 
<!DOCTYPE map PUBLIC "-//OASIS//DTD XDITA Map//EN" 
"file://.../dita-ot-2.2.1/plugins/org.oasis-open.dita.v1 
_2/dtd/technicalContent/dtd/map.dtd"> 
<map xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" 
    title="Empty map" ditaarch:DITAArchVersion="1.2" domains="(topic delay-d) 
    (map mapgroup-d)       (topic indexing-d) 
    (map glossref-d)       (topic hi-d) 
    (topic ut-d)       (topic hazard-d) 
    (topic abbrev-d)       (topic pr-d) 
    (topic sw-d)       (topic ui-d) 
    " class="- map/map "> 
</map> 

Но если я закомментировать import libxsltmod , результат:

<?xml version="1.0"?> 
<!DOCTYPE map PUBLIC "-//OASIS//DTD XDITA Map//EN" 
"file://.../dita-ot-2.2.1/plugins/org.oasis-open.dita.v 
1_2/dtd/technicalContent/dtd/map.dtd"> 
<map title="Empty map"> 
</map> 

Таким образом, libxsltmod делает что-то, чтобы активировать расширение атрибутов по умолчанию. Не могли бы вы предложить, что и как я могу активировать эту функцию через python?

ответ

2

Я понятия не имею, как libxsltmod позволяет эту установку в глобальном масштабе, но, как правило, атрибуты DTD по умолчанию добавляются с parser optionXML_PARSE_DTDATTR. Используйте readDoc вместо parseDoc для обеспечения возможности анализатора:

xmldoc = libxml2.readDoc(s, None, None, libxml2.XML_PARSE_DTDATTR) 

Или, если вы хотите заменить сущности:

flags = libxml2.XML_PARSE_NOENT | libxml2.XML_PARSE_DTDATTR 
xmldoc = libxml2.readDoc(s, None, None, flags) 
+0

спасибо за указание функции 'readDoc'. Однако, пожалуйста, исправьте свой ответ, флаги должны быть 'libxml2.XML_PARSE_NOENT | libxml2.XML_PARSE_DTDATTR' – olpa

1

Я принял ответ от @nwellnhof, но хотелось бы также опубликовать мои исследования.

Функция инициализации initlibxsltmod из libxslt модуля устанавливает глобальную переменную:

xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 

я не нашел никакой возможности получить доступ к этой переменной из кода связывания libxml2 Python/C, но я обнаружил, что эта переменная используются для инициализации «контекст синтаксического анализатора» по умолчанию, и можно создавать и использовать контекст синтаксического анализатора вручную:

ctxt = libxml2.createDocParserCtxt(s) 
opts = libxml2.XML_PARSE_NOENT | libxml2.XML_PARSE_DTDATTR 
ctxt.ctxtUseOptions(opts) 
ctxt.parseDocument() 
xmldoc = ctxt.doc() 
del ctxt 

Питон/C функция readDoc выполняет exacly этого путь (создать контекст, задать параметры, разбор). Ручное контекстное создание многословно, но, вероятно, необходимо в некоторой ситуации.