美好的一天,
我的XSLT将XLM页面转换为HTML页面。现在我遇到了一个问题,这对我来说似乎并不重要。我希望指向正确的方向。
我想减少我必须在原始XML文件中写入的行数。我想要的是类似于XSLT预处理器,在XSLT处理之前将一些XML标记转换为一组其他XML标记。如果可能的话,我想在同一个XML文档中保留替换行和替换行(因此,没有包含文件样式的解决方案)。
示例:
我的XML文件通常包含重复的多行,例如以下简化代码段:
<img>
<url>a_midi.jpg</url>
</img>
<img>
<url>b_midi.jpg</url>
</img>
<img>
<url>c_midi.jpg</url>
</img>
如果我可以将这些多行包含在宏标记中,放在XML文件开头附近,那就太棒了,如下所示:
<macro id="name_a">
<img>
<url>a_midi.jpg</url>
</img>
<img>
<url>b_midi.jpg</url>
</img>
<img>
<url>c_midi.jpg</url>
</img>
</macro>
我不会在各个地方反复重复初始行,而是使用类似的东西:
<use_macro id="name_a"/>
现在,我当然可以指示XSLT在遇到* use_macro *标记时处理与名称“name_a”匹配的模板宏。
但是,这不是我想要的。原因是,上面的 img 标签本身包含在另一个周围的标签中,比如* multi_img *。处理此标记的XSLT会考虑其中包含的许多其他标记,这些标记决定了XML如何转换为HTML(有时 img 标记甚至需要以不同的方式多次处理。)
因此,我正在寻找的是一种
的方式(1)首先将XML * use_macro *转换为宏标记中包含的XML;
(2)然后使用XSLT处理生成的XML,就好像首先没有* use_macro *标记一样。
可能解决方案很明显,我只是过度劳累,但我找不到我需要的东西(即使没有花时间与Jeni Tennison的“XSLT和XPath /边缘”)。
我感谢指针(也是Tennison的书中的相应章节),或者只是声明“它无法完成”。提前谢谢。
此致 草本植物
答案 0 :(得分:1)
听起来你必须做两个步骤。
显而易见且最简单的解决方案可能是生成临时xml文件。只扩展了use_macro
。比调用此临时文件的原始xslt。
仅使用一个xlst处理器调用执行此两个步骤取决于xslt版本。
使用xslt-1.0,您需要使用node-set()
之类的扩展程序
第一步生成一个带有完整xml文件的变量但扩展use_macro
比应用原来的XLST,如:
<xsl:apply-templates select="exsl:node-set($xml_whith_use_macro_extended)/*" />
对于xsltpoc,这将执行:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"
>
<xsl:strip-space elements="*" />
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()" mode="extend">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="extend"/>
</xsl:copy>
</xsl:template>
<xsl:template match="macro" mode="extend" />
<xsl:template match="use_macro" mode="extend" >
<xsl:copy-of select="//macro[@id = current()/@id]" />
</xsl:template>
<xsl:template match="@*|node()" >
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="xml_whith_use_macro_extended" >
<xsl:apply-templates mode ="extend" select="/*" />
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="exsl:node-set($xml_whith_use_macro_extended)/*" />
</xsl:template>
<!-- other temlates -->
</xsl:stylesheet>