1

私はlxml python libを使用しています。

次のような製品 xml があるとします。

<product id='123' />

そして、xsl テンプレートを適用したい:

<xsl:template match="product">
    <ssi:include virtual="/ssi/reviews/{@id}"/>
</xsl:template>

ssi:include は、nginx ssi 命令をコメントとして HTML コードに挿入する単純な lxml 拡張機能です。問題は、@id を評価し、属性を virtual="/ssi/include/123" として渡すことです。方法はありますか?私は解決策を見つけて、今ではそれを使用しています:

import lxml.etree
import re
from copy import deepcopy

ns = '{ssi}'

# ssi extensions
class SsiExtElement(lxml.etree.XSLTExtension):
    def execute(self, context, self_node, input_node, output_parent):
        _, tag = self_node.tag.split('}')
        tmp = lxml.etree.Element('tmp')
        for k, v in self_node.attrib.items():
            if re.search('\{(.*)\}', v): #here we search {xpath} values to evaluate
                elem = deepcopy(input_node)
                matches = re.findall('\{(.*)\}', v)
                for match in matches:
                    v = v.replace('{%s}' % match, elem.xpath(match)[0])
            tmp.set(k, v)
        self.process_children(context, output_parent=tmp)
        attrs = ' '.join(u'%s="%s"' % (k, v) for k, v in tmp.attrib.items())
        ssi = lxml.etree.Comment(u'#%s %s' % (tag, attrs))
        output_parent.append(ssi)
        for node in tmp:
        output_parent.append(node)
        if (self_node.tag.replace(ns,'') in ('if', 'else', 'elif')
            and self_node.getnext().tag.replace(ns, '') not in ('else', 'elif')):
        output_parent.append(lxml.etree.Comment(u'#endif'))
4

2 に答える 2

1

xsl:attribute で試してください

<xsl:template match="product">
    <ssi:include>
       <xsl:attribute name="virtual">
          <xsl:value-of select="concat('/ssi/reviews/',@id)"/>
       <xsl:attibute>
    </ssi:include>
</xsl:template>
于 2013-04-29T13:57:40.677 に答える
0

私は同じ状況にあり、私が見ていることから、2つの道をたどることができます:

  • 用途context.context_node:無地etree.Elementでありxpath()。論理的には と同じinput_nodeです。このようにして、ソース ドキュメント内の任意の XPath を評価できます。
  • 子要素を介してパラメーターを渡し、process_children()それらを評価するために使用します。

例:

<ssi:include>
  <virtual value="/ssi/reviews/{@id}" />
</ssi:include>

2 番目のアプローチでは、XSLT 変数も評価できます。つまり、私の場合は次のようになります。

<path:make-directory>
  <target value="{$target}" />
</path:make-directory>

残りのすべて、特にapply_templates()機能していないようです。

于 2013-09-29T08:46:33.060 に答える