Динамически решить, какую таблицу стилей XSL использовать - PullRequest
4 голосов
/ 05 августа 2010

Я пытаюсь создать сайт, который (помимо прочего) будет отображать данные, содержащиеся в XML-файлах. Я использую таблицы стилей xsl для форматирования всего, но некоторые страницы имеют похожее содержание. Вместо того, чтобы создавать несколько листов XML с дублирующимися данными, есть способ сообщить 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 ]

1 голос
/ 05 августа 2010

В такой ситуации я использую макеты, каждая из которых содержится в отдельном XML-документе.

Используемый макет (имя файла) может быть передан в качестве параметра для преобразования, илион может быть определен динамически в рамках преобразования.

С этого момента доступ к XML-документу Layout можно получить с помощью функции XSLT document ():

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

Затем можно выполнить:

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

Это шаблон проектирования * XSLT fill in the blanks * .

0 голосов
/ 05 августа 2010

Вы можете использовать Client Side XSLT.Укажите PI в ваших XML-документах и ​​в конкретную таблицу стилей включите основную таблицу стилей макета.

Вы можете свободно проверять и использовать 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>

Примечание : Основная проблема с вашим реквизитом - это то же ограничение документа (то есть, тот же URI документа, нет другого PI, нет разных метаданных URI макета), из-за чего вам остается передавать только javascriptмакет URI, парам.Пока браузер не поддерживает XPath 2.0 fn:document-uri(), вы можете анализировать URL-запрос.Конечно, вы могли бы использовать какое-то расширение (например, MSXSL script), но было бы трудно заставить его работать в кросс-браузерном режиме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...