XSLT дублирует описание, когда я повторяю XML - PullRequest
0 голосов
/ 22 сентября 2010

Я использую XSLT для рекурсии некоторого XML, а затем применяю HTML к выводу.Он получит данные, но дублирует описание родительского элемента, и я не уверен, почему?Я уверен, что это прямо перед моим лицом, но я этого не вижу.Он вставляется сразу после тега <ul> при переходе на следующий уровень в XML.

Пример XML:

<root>
    <filters>
        <filter ID="My Test">
            <item id="1">
                <description>MyTest Descrip</description>
                <item id="1">
                    <description>Sub Level - 1</description>
                </item>
                <item id="2">
                    <description>Sub Level - 2</description>
                </item>
                <item id="3">
                    <description>Sub Level - 3</description>
                <item id="4">
                <description>Sub Level 2 - 1</description>
                </item>
                    <item id="5">
                    <description>Sub Level 2 - 2</description>
                    </item>
                </item>
            </item>
        </filter>
    </filters>
</root>

Пример XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="filter">
    <xsl:variable name="dataID" select="@ID"/>
        <ul class="searchdata">
            <xsl:apply-templates select="item"/>
        </ul>
    </xsl:template>
    <xsl:template match="item">
    <li>
        <xsl:variable name="searchID" select="@id"/>
        <input id="{$searchID}" type="checkbox"/>
        <label for="{$searchID}">
            <xsl:value-of select="description"/>
        </label>
        <xsl:if test="item">
        <ul>
            <xsl:apply-templates />
        </ul>
        </xsl:if>
    </li>
</xsl:template>
</xsl:stylesheet>

Вывод HTML:

<?xml version="1.0" encoding="utf-8"?>

    <ul class="searchdata"><li><input id="1" type="checkbox" /><label for="1">MyTest Descrip</label><ul>
    MyTest Descrip
     <li><input id="1" type="checkbox" /><label for="1">Sub Level - 1</label></li>
     <li><input id="2" type="checkbox" /><label for="2">Sub Level - 2</label></li>
          <li><input id="3" type="checkbox" /><label for="3">Sub Level - 3</label><ul>
              Sub Level - 3
              <li><input id="4" type="checkbox" /><label for="4">Sub Level 2 - 1</label></li>

              <li><input id="5" type="checkbox" /><label for="5">Sub Level 2 - 2</label></li>
          </ul></li>
     </ul></li></ul>

Буду признателен за любые предложения.

Спасибо.

1 Ответ

2 голосов
/ 22 сентября 2010

Проблема в том, что вы не обращаете внимания на встроенные правила , встроенные правила для текстового узла и, в частности, элементов.

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

Итак, вам нужнодобавьте это правило полосовых текстовых узлов:

<xsl:template match="text()"/>

И тогда вы получите:

<ul class="searchdata">
    <li>
        <input id="1" type="checkbox" />
        <label for="1">MyTest Descrip</label>
        <ul>
            <li>
                <input id="1" type="checkbox" />
                <label for="1">Sub Level - 1</label>
            </li>
            <li>
                <input id="2" type="checkbox" />
                <label for="2">Sub Level - 2</label>
            </li>
            <li>
                <input id="3" type="checkbox" />
                <label for="3">Sub Level - 3</label>
                <ul>
                    <li>
                        <input id="4" type="checkbox" />
                        <label for="4">Sub Level 2 - 1</label>
                    </li>
                    <li>
                        <input id="5" type="checkbox" />
                        <label for="5">Sub Level 2 - 2</label>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

Кроме того, эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="item"/>
    <xsl:template match="item[1]">
        <ul class="searchdata">
            <xsl:apply-templates select="../item" mode="li"/>
        </ul>
    </xsl:template>
    <xsl:template match="item" mode="li">
        <li>
            <input id="{@id}" type="checkbox"/>
            <xsl:apply-templates/>
        </li>
    </xsl:template>
    <xsl:template match="description">
        <label for="{../@id}">
            <xsl:value-of select="."/>
        </label>
    </xsl:template>
</xsl:stylesheet>

Примечание : здесь есть правило, соответствующее элементу description, которое имеет более высокий приоритет, чем встроенное правило шаблона для элементов (применять шаблоны к дочерним узлам).

И, наконец, эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="node()">
        <xsl:apply-templates select="node()[1]|following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="item[1]">
        <ul class="searchdata">
            <xsl:call-template name="item"/>
        </ul>
    </xsl:template>
    <xsl:template match="item" name="item">
        <li>
            <input id="{@id}" type="checkbox"/>
            <xsl:apply-templates select="node()[1]"/>
        </li>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="description">
        <label for="{../@id}">
            <xsl:value-of select="."/>
        </label>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
</xsl:stylesheet>

Примечание : при этом используется последовательное («наиболее мелкозернистый обход») вместо применения рекурсивного шаблона.

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