动态决定使用哪个XSL样式表

时间:2010-08-05 17:20:22

标签: html xml xslt

我正在尝试创建一个网站,其中(除其他外)将显示xml文件中包含的数据。我正在使用xsl样式表来格式化所有内容,但有些页面具有相似的内容。有没有办法告诉xsl显示数据的位置,并让它确定要使用的布局。

示例:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">

<xsl:choose>
  <xsl:if test="something">
    <!-- Format data one way -->
  </xsl:if>
  <xsl:otherwise>
    <!-- Format data another way -->
  </xsl:otherwise>
</xsl:choose>

</xsl:template>
</xsl:stylesheet>

该网站托管在一个较大的网站上,不允许其微型网站使用任何服务器端脚本,所以我的选项在这里受到严格限制。

2 个答案:

答案 0 :(得分:1)

在这种情况下,我使用布局,每个布局都包含在一个单独的XML文档中。

要使用的(文件名)布局可以作为参数传递给转换,也可以在转换中动态确定。

从此刻开始,可以使用XSLT document()函数访问Layout XML文档:

<xsl:variable name="vDocLayout" select="document($pLayout)"/>

然后你可以发出:

<xsl:apply-templates select="$vDocLayout"/>

这是“ fill in the blanks ”XSLT设计模式

答案 1 :(得分:0)

您可以使用客户端XSLT。在XML文档中提供PI,在特定样式表中包含主布局样式表。

可以自由检查并使用http://www.aranedabienesraices.com.ar作为示例。

编辑3 :几乎完整的递归示例。

XML文档“layoutA.xml”:

<html xmlns:inc="include">
    <body>
        <h1>Birthday</h1>
        <dl inc:in-iter="person">
            <dt inc:path="name"></dt>
            <dd inc:path="date"></dd>
        </dl>
    </body>
</html>

输入XML文档:

<data>
    <person>
        <name>Bob</name>
        <date>2010-02-23</date>
        <link>http://example.org/bob</link>
    </person>
    <person>
        <name>Alex</name>
        <date>2010-02-23</date>
        <link>http://example.org/alex</link>
    </person>
</data>

样式表:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:inc="include">
    <xsl:param name="pLayout" select="'layoutA.xml'"/>
    <xsl:template match="/">
        <xsl:apply-templates select="document($pLayout)/*">
            <xsl:with-param name="context" select="*"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:param name="context"/>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:with-param name="context" select="$context"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[@inc:path]">
        <xsl:param name="context"/>
        <xsl:copy>
            <xsl:apply-templates select="@*">
                <xsl:with-param name="context" select="$context"/>
            </xsl:apply-templates>
            <xsl:value-of select="$context/*[name()=current()/@inc:path]"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[@inc:in-iter]" priority="1">
        <xsl:param name="context"/>
        <xsl:variable name="me" select="."/>
        <xsl:copy>
            <xsl:apply-templates select="@*">
                <xsl:with-param name="context" select="$context"/>
            </xsl:apply-templates>
            <xsl:for-each select="$context/*[name()=current()/@inc:in-iter]">
                <xsl:apply-templates select="$me/node()">
                    <xsl:with-param name="context" select="."/>
                </xsl:apply-templates>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[@inc:out-iter]" priority="1">
        <xsl:param name="context"/>
        <xsl:variable name="me" select="."/>
        <xsl:for-each select="$context/*[name()=current()/@inc:out-iter]">
            <xsl:element name="{name($me)}" namespace="{namespace-uri($me)}">
                <xsl:apply-templates select="$me/@*|$me/node()">
                    <xsl:with-param name="context" select="."/>
                </xsl:apply-templates>
            </xsl:element>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="@inc:path|@inc:in-iter|@inc:out-iter" priority="1"/>
    <xsl:template match="@inc:*">
        <xsl:param name="context"/>
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="$context/*[name()=current()]"/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

输出:

<html xmlns:inc="include">
    <body>
        <h1>Birthday</h1>
        <dl>
            <dt>Bob</dt>
            <dd>2010-02-23</dd>
            <dt>Alex</dt>
            <dd>2010-02-23</dd>
        </dl>
    </body>
</html>

将参数pLayout作为'layoutB.xml'和“layoutB.xml”传递:

<html xmlns:inc="include">
    <body>
        <h1>Friends</h1>
        <ul>
            <li inc:out-iter="person">
                <a inc:href="link" inc:path="name"></a>
            </li>
        </ul>
    </body>
</html>

输出:

<html xmlns:inc="include">
    <body>
        <h1>Friends</h1>
        <ul>
            <li>
                <a href="http://example.org/bob">Bob</a>
            </li>
            <li>
                <a href="http://example.org/alex">Alex</a>
            </li>
        </ul>
    </body>
</html>

注意:您的requeriment的主要问题是相同的文档限制(因此,相同的文档URI,没有不同的PI,没有不同的布局URI元数据)只留给javascript传递布局URI参数。在浏览器支持XPath 2.0 fn:document-uri()之前,您可以解析URL查询。当然,你可以使用一些扩展名(例如MSXSL script),但要使它跨浏览器工作会很困难。