XSLT。在将XSLT处理成HTML之前,我需要将XML预处理到其他XML中。这是怎么做到的?

时间:2013-06-17 09:37:29

标签: xml xslt preprocessor

美好的一天,

我的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的书中的相应章节),或者只是声明“它无法完成”。提前谢谢。

此致 草本植物

1 个答案:

答案 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>