Цикличное выполнение и рекурсия на основе параметра передаются

Мне организовали XML как ниже -

<section name="Parent 1 Text here" ID="1" >
  <section name="Child 1 Text here" ID="11">
  </section>
  <section name="Child 2 Text here" ID="12">
    <section name="GrandChild Text here"  ID="121" >
    </section>
  </section>
</section>

<section name="Parent 2 Text here" ID="2" >
  <section name="Child 1 Text here" ID="22">
  </section>
  <section name="Child 2 Text here" ID="23">
    <section name="GrandChild Text here"  ID="232" >
    </section>
  </section>
</section>         

Я должен произвести ниже вывода XML -

<section name="Parent 1 Text here" ID="1" >
  <section name="Child 2 Text here" ID="12">
    <section name="GrandChild Text here"  ID="121" >
    </section>
  </section>
</section>

<section name="Parent 2 Text here" ID="2" >
  <section name="Child 2 Text here" ID="23">
  </section>
</section>

Я имею к achive выше использования преобразования XSLT 1.0. Я планировал передать разделенную строку запятой в качестве параметра со значением = "1,12,121,2,23"

Мой вопрос - Как циклично выполнить запятую, разделил параметр в XSLT 1.0? Есть ли более простой способ достигнуть вышеупомянутого. Помните, что я должен сделать это в XSLT 1.0, Ваша справка ценится.

1
задан Justin Johnson 19 May 2010 в 01:30
поделиться

2 ответа

Вот альтернатива подходу Яна Виллема Б. Я не утверждаю, что это лучше или хуже. Я представляю его по двум причинам:

  1. Возможно, вы захотите увидеть, как будет выглядеть рекурсивный подход

  2. Он ведет себя по-разному для некоторых входных данных (хотя он ведет себя так же для данных вашего примера). В частности, если ваш фильтр включает два узла, которые являются потомками одного и того же узла, эта таблица стилей выведет две вложенные структуры данных, каждая с одним листовым узлом, в то время как ответ Яна Виллема B выведет одну вложенную структуру с двумя листовыми узлами. Не знаю, что тебе нужно.

Для моей таблицы стилей вы должны передать фильтр, перечисляющий только те листовые узлы, которые вам нужны. Он найдет своих предков. Для этого я предположил, что ваш корневой узел называется

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

    <xsl:param name="descendant-ids" select="'121,23'"/>

    <xsl:template match="/">
        <doc>
            <xsl:call-template name="recurse-ids">
                <xsl:with-param name="ids" select="concat($descendant-ids,',')"/>
            </xsl:call-template>
        </doc>
    </xsl:template>

    <xsl:template name="recurse-ids">
        <xsl:param name="ids"/>
        <xsl:variable name="id" select="substring-before($ids,',')"/>
        <xsl:variable name="remaining-ids" select="substring-after($ids,',')"/>
        <xsl:apply-templates select="/doc/section">
            <xsl:with-param name="id" select="$id"/>
        </xsl:apply-templates>
        <xsl:if test="$remaining-ids">
            <xsl:call-template name="recurse-ids">
                <xsl:with-param name="ids" select="$remaining-ids"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template match="section">
        <xsl:param name="id"/>
        <xsl:if test="starts-with($id,@ID)">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()">
                    <xsl:with-param name="id" select="$id"/>
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:if>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
0
ответ дан 3 September 2019 в 00:29
поделиться

Рекурсия не обязательно является решением. В принципе, ваша строка с запятыми может быть применена как фильтр:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:param name="filter">1,12,121,2,23</xsl:param>

  <xsl:template match="section">
    <xsl:if test="contains(concat(',', $filter, ','), concat(',', @ID, ','))">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:if>
  </xsl:template>

  <!-- copy the rest -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
2
ответ дан 3 September 2019 в 00:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: