Как добавить / протестировать несуществующий элемент в шаблоне XLS? - PullRequest
1 голос
/ 16 июня 2011

Контекст

Это для настраиваемой веб-части запроса (CQWP) в SharePoint 2007 .Я извлекаю список событий из календаря и хочу отобразить список текущего состояния системы для всех систем, даже если у них нет текущего события.

Список упорядочен по имени системы.

XML получено

Предположим, у вас есть либо XML:

<events>
    <event>
        <system>A</system>
        <state>1</state>
    </event>
    <event>
        <system>B</system>
        <state>2</state>
    </event>
    <event>
        <system>C</system>
        <state>3</state>
    </event>
</events>

ИЛИ

<events>
    <event>
        <system>A</system>
        <state>1</state>
    </event>

    <event>
        <system>C</system>
        <state>2</state>
    </event>
</events>

Примечание : 3 статических система (A, B или C).У них не может быть текущего события (я не указывал дату начала / окончания, поскольку она не нужна для вопроса.)

Требуется вывод данных

Я хочу, чтобы мой вывод XSL был таким:

<table>
    <tr>
        <th>System</th>
        <th>State</th>
    </tr>
    <tr>
        <td>A</td>
        <td>1</td>
    </tr>
    <tr>
        <td>B</td>
        <td>1</td>
    </tr>
    <tr>
        <td>C</td>
        <td>3</td>
    </tr>
</table>

То есть я хочу получить вывод для всех 3 систем, , даже если у них нет текущего события (следовательно, не в XML (состояние по умолчанию 1)).Да, да, в одной системе может быть 2+ текущего события.(<td>A</td><td>1</td></tr><tr><td>A</td><td>2</td>).Ответ perfect объединит одно и то же системное событие и отобразит только самое высокое состояние, но я могу обойтись без него.

Current XSL

Вот текущий шаблон, который у меня есть:

<xsl:template name="system" match="Row[@Style='system']" mode="itemstyle">
    <xsl:if test="count(preceding-sibling::*)=0">
        <table><tr><th>System</th>
        <th>State</th></tr>
    </xsl:if>
    <tr>
            <td><xsl:value-of select="@System"/></td>
             <td><xsl:value-of select="@State"/></td>
    </tr>
    <xsl:if test="count(following-sibling::*)=0">
        </table>
    </xsl:if>
</xsl:template>

Что я думал

Я думал, что могу использовать переменную (или 3?), Чтобы содержать мой список (статической) системы

<xsl:variable name="Systems">A,B,C</xsl:variable> 

<xsl:variable name="System1">A</xsl:variable> 
<xsl:variable name="System2">B</xsl:variable> 
<xsl:variable name="System3">C</xsl:variable> 

Затем в XSLпроверьте, равняется ли <xsl:value-of select="@System"/> значение этой / этой переменной.

Вопросы

Это выполнимо?

Не могли бы вы предложить мне поступить иначе, если да, то как?

Как сравнить мои переменные с <xsl:value-of select="@System"/>?

Bonus : Как я могу объединить одно и то же системное событие и отобразить только самое высокое состояние?

Ответы [ 3 ]

1 голос
/ 17 июня 2011

Возможно, может быть более короткое решение. Я все равно не мог понять. Это мое предложение XSLT 2.0:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:variable name="default">
        <event>
            <system>A</system>
            <state>1</state>
        </event>
        <event>
            <system>B</system>
            <state>1</state>
        </event>
        <event>
            <system>C</system>
            <state>1</state>
        </event>
    </xsl:variable>

    <xsl:template match="events">
        <table>
            <tr>
                <th>System</th>
                <th>State</th>
            </tr>

            <xsl:choose>
                <xsl:when test="event[system='A']">
                    <xsl:apply-templates select="event[system='A'][1]"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="$default/event[system='A']"/>
                </xsl:otherwise>
            </xsl:choose>

            <xsl:choose>
                <xsl:when test="event[system='B']">
                    <xsl:apply-templates select="event[system='B'][1]"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="$default/event[system='B']"/>
                </xsl:otherwise>
            </xsl:choose>

            <xsl:choose>
                <xsl:when test="event[system='C']">
                    <xsl:apply-templates select="event[system='C'][1]"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="$default/event[system='C']"/>
                </xsl:otherwise>
            </xsl:choose>

        </table>        
    </xsl:template>


    <xsl:template match="event">
        <xsl:variable name="maxval" select="max(
            ../event[system=current()/system]/state)"/>
        <tr>
            <td>
                <xsl:value-of select="system"/>
            </td>
            <td>
                <xsl:value-of select="$maxval"/>
            </td>
        </tr>
    </xsl:template>

</xsl:stylesheet>
1 голос
/ 17 июня 2011

Это выполнимо. Если у вас есть только 3 сайта, проще скопировать и вставить для проверки A, B и C по отдельности. Если вы хотите более гибкое решение, я бы использовал функцию расширения node-set (), но она может отсутствовать в вашем парсере. (и, похоже, в XSLT 2.0 есть лучший способ, о котором я не знаю.)

<xsl:variable name="root" select="/"/>

<xsl:variable name="system">
    <system>A</system>
    <system>B</system>
    <system>C</system>  
</xsl:variable>

<xsl:template match="/">
<table>
<xsl:for-each select="msxsl:node-set($system)/system">
    <tr>
        <td><xsl:value-of select="text()"/></td>
        <td>
            <xsl:for-each select="$root/events/event[system=current()]">
                <xsl:sort select="date" order="descending"/>
                    <xsl:if test="position()=1">
                        <xsl:value-of select="state"/>
                    </xsl:if>

            </xsl:for-each>
        </td>
    </tr>
</xsl:for-each>
</table>
</xsl:template>

У меня нет парсера, чтобы убедиться, что функция расширения работает, но, надеюсь, он запустится.

0 голосов
/ 20 июня 2011

Спасибо за ответ, ваш пример помог мне понять XSL.Однако, поскольку это было для SharePoint, я осознал, что мне придется играть в рамках ...

Случай без текущего события обрабатывается в mainStyle.xsl и отображать только html по умолчанию.

Элементы обрабатываются в itemStyle.xsl , один за другим.Большая часть моего кода была размещена там.

Сначала я создал кучу переменных:

    <xsl:variable name="testACCP">
            <xsl:choose><xsl:when test="count(../Row[@Systeme='A'])>0">1</xsl:when>
            [...]
    </xsl:variable>

Затем я строю свое решение, начиная с заголовка, когда я был на своем первом узле.

     <xsl:if test="count(preceding-sibling::*)=0">
        <xsl:text disable-output-escaping="yes">
            &lt;table width="100%" border="0" cellspacing="0" cellpadding="3" &gt;
            [...]

Если бы в Системе не было события, я бы знал это по моей переменной и отобразил бы соответственно

<xsl:if test="$testA=0">
            <tr id="linkitem" class="item" style="background:#f0fff3">
                    <td>A</td><td>OK</td>
                    [...]

Что касается отображения только максимального значения, то оно было отменено,Есть некоторая ценность знать, что в конце концов у вас есть 2 текущих события, влияющих на систему.

Это решение работает, но оно довольно глупо, создавая множество переменных для элементов для тестирования в группе ...оптимизировать, потребуется сильно модифицированный mainstyle.xsl или полноценный WebPart.

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