1

再会,

我的 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* 转换为包含在macro标签中的XML;

(2) 然后使用 XSLT 处理生成的 XML,就好像一开始根本没有 *use_macro* 标记一样。

可能解决方案很明显,我只是过度劳累,但我找不到我需要的东西(即使在花了一些时间阅读 Jeni Tennison 的“XSLT 和 XPath / On the edge”之后也找不到)。

我很欣赏指针(也指向 Tennison 书中的相应章节),或者只是“它不能完成”的陈述。提前致谢。

问候, 香草

4

1 回答 1

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>
于 2013-06-17T10:33:08.123 回答