Передавать фрагменты XML как параметры таблицы стилей с помощью lxml? - PullRequest
0 голосов
/ 18 ноября 2009

Я начинаю использовать lxml в Python для обработки документов XML / XSL, и в целом это кажется очень простым. Однако я не могу найти способ передать фрагмент XML в качестве параметра таблицы стилей при выполнении перевода.

Например, в PHP можно передавать DOMDocument фрагменты XML в качестве параметров таблицы стилей, чтобы в таблице стилей можно было иметь сложные параметры:

$xml = new DOMDocument();
$xml->loadXML('<root><node/></root>');

$xsl = new DOMDocument();
$xsl->loadXML('<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" omit-xml-declaration="yes" 
    indent="yes" media-type="text/html" />
<xsl:param name="a" />

<xsl:template match="/">
<html>
  <body>
    <xsl:value-of select="$a/foo/bar/text()" />
  </body>
</html>
</xsl:template>

</xsl:stylesheet>');

$fragment = new DOMDocument();
$fragment->loadXML('<foo><bar>baz</bar></foo>');

$proc = new XSLTProcessor;
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsl);

$param_ns = '';
$param_name = 'a';
$proc->setParameter($param_ns, $param_name, $fragment->documentElement);

Что приведет к:

<html>
  <body>
  baz
  </body>
</html>

Как это сделать, используя lxml?

Ответы [ 3 ]

1 голос
/ 18 ноября 2009

Насколько я знаю, вы можете использовать выражения xpath (или результат метода etree.XSLT.strparam () для строк с кавычками) в lxml (на данный момент в любом случае).

Однако, поскольку вы можете использовать выражения xpath, это означает, что вы можете "обойти", используя пользовательскую функцию расширения xpath , которая возвращает рассматриваемый элемент. Другим способом может быть использование стандартной функции xpath document () и использование настраиваемого распознавателя

0 голосов
/ 03 января 2010

Вы можете использовать функцию расширения python для возврата документа etree.XML в xslt. Вот самый минимальный пример. Он регистрирует глобальное пространство имен (uri: params), связывает функцию с методом «params» в этом пространстве имен. Это используется таблицей стилей для достижения функции расширения. Не забудьте объявление xmlns: ptest в таблице стилей.

хмм, похоже, мне придется добавить html-сущности для представления символа <в этом коде. Я также положил его в <a href="http://bkc.pastebin.com/f67461ccc" rel="nofollow noreferrer">http://bkc.pastebin.com/f67461ccc


from lxml import etree

stylesheet = etree.XML("""
    <xsl:stylesheet version="1.0"
         xmlns:ptest="uri:params"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:variable name="params" select="ptest:params()" />
         <xsl:template match="/">
             <name_is><xsl:value-of select="$params/name" /></name_is>
         </xsl:template>
     </xsl:stylesheet>
""")

def params(context):
    # this is the extension function, it returns
    # a etree.XML document
    return etree.XML(
        """<params>
                <name>fred
        </params>"""
        )


def test():
    """test passing document to xslt via python extension function

    >>> test()
    <?xml version="1.0"?>
    <name_is xmlns:ptest="uri:params">fred
    <BLANKLINE>
    """    
    ns = etree.FunctionNamespace('uri:params') # register global namespace
    ns['params'] = params # define function in new global namespace
    transform = etree.XSLT(stylesheet)
    print str(transform(etree.XML("""<source />""")))

if __name__ == "__main__":
    import doctest
    doctest.testmod()
0 голосов
/ 19 ноября 2009

Я считаю, что то, что вы ищете, может быть выполнено с помощью lxml.etree.XSLT . Хорошие примеры можно найти в разделе XSLT на странице, документирующей XPath и XSLT с lxml .

...